简体   繁体   中英

Cannot properly update frontend on rerender reactjs using useEffect

So I was making a blog application where only logged in users can add new blogs. To start, when a user logs in, they will see all the blogs they have previously created on the frontend along with a form to add new ones. However, when the logged in user tries to add a new blog, it updates on the frontend but returns back to the original list they had before when the page is refreshed. I can see the updated blog list when I log out and log back in again. I actually used local storage to make sure that logged in users remain logged in after a new render. I just need help in making sure the new blogs added after login remain on the frontend after a render.

I think I have an idea why it is happening but I am not sure. So whenever my loginService function is called within the handleLogin function, the server sends back the user info which includes all the blogs they have created. The problem with refreshing is due to the same list of blogs that were there at the time of login unless you log out and log in again.

Any help would be greatly appreciated.

ReactJS code

import { useState, useEffect } from 'react'
import Blog from './components/Blog'
import blogService from './services/blogs'
import loginService from './services/login'
import userService from './services/user'

const App = () => {
  const [blogs, setBlogs] = useState([])
  const [newBlogs, setNewBlogs] = useState([])
  const [user, setUser] = useState(null)
  const [username, setUsername] = useState('')
  const [password, setPassword] = useState('')
  const [errorMsg, setErrorMsg] = useState('')

  const [blogTitle, setBlogTitle] = useState('')
  const [blogAuthor, setBlogAuthor] = useState('')
  const [blogUrl, setBlogUrl] = useState('')

  useEffect( () => {
    if(user != null){
      setBlogs(user.blog.concat(newBlog))
    }
    console.log("blogs is", blogs)
  }, [user])


//Seeing if a user is logged in on rerender

  useEffect(() => {
    const loggedInUser = window.localStorage.getItem('loggedBlogUser')
    if(loggedInUser){
      const user = JSON.parse(loggedInUser)
      setUser(user)
    }
  },[])


  
// Logging in users
  const handleLogin = async (event) => {
    event.preventDefault()
    console.log("Logging in,", username, password)
    try {
      const user = await loginService({username, password})
      blogService.setToken(user.token)
      window.localStorage.setItem('loggedBlogUser', JSON.stringify(user))
      setUser(user)
      setUsername('')
      setPassword('')
    }
    catch(error){
      setErrorMsg('Wrong credentials')
      setTimeout(() => {
        setErrorMsg(null)
      },[])
    }
  }

//Logging out users
  const handleLogout = () => {
    window.localStorage.removeItem('loggedBlogUser')
    setUser(null)
    setBlogs([])
  }

//Adding new blogs
  const addNewBlog = async (e) => {
    e.preventDefault()

    console.log("User here is", user)

    try {
      const newBlog = {
        title: blogTitle,
        author: blogAuthor,
        url: blogUrl
      }
      await blogService.createBlog(newBlog)
      setBlogs(blogs.concat(newBlog))
      setNewBlogs(newBlogs.concat(newBlog))
      setBlogTitle('')
      setBlogAuthor('')
      setBlogUrl('')
    }
    catch(error){
      console.log("error adding new blog", error)
    }

    console.log("blogs is", blogs)
  }

  return (
    <div>
      <h2>blogs</h2>
      {user == null && <div className="login-form">
      <form onSubmit={handleLogin}>
      <div className="username-container">
        username
        <input type='text' value={username} onChange={(e) => setUsername(e.target.value)} name='username'/>
      </div>
      <div className="password-container">
        password
        <input type='password' value={password} onChange={(e) => setPassword(e.target.value)} name='password'/>
      </div>
      <button type='submit'>Login</button>
      </form>
      </div>}
      {user != null && <div className="notes">
        <p>{user.name} logged in <button onClick={handleLogout}>logout</button></p>
      </div>}
      {user != null && <div className="addBlog-container">
      <b>create new</b>
      <form onSubmit={addNewBlog}>
        <label>Title:</label><input type="text" value={blogTitle} onChange={(e) => setBlogTitle(e.target.value)} name="blog-title"/>
        <label>Author:</label><input type="text" value={blogAuthor} onChange={(e) => setBlogAuthor(e.target.value)} name="blog-author"/>
        <label>Url:</label><input type="text" value={blogUrl} onChange={(e) => setBlogUrl(e.target.value)} name="blog-url"/>
        <button type='submit'>create blog</button>
      </form>
      </div>}
      {blogs != null && blogs.map(blog =>
        <Blog key={blog.id} blog={blog} />
      )}
    </div>
  )
}

export default App

At first you are updating blogs from user.blog but in update blog you are only updating blogs variable, that's why new blog disappears as soon as you refresh. Try after updating user.blog with new blog.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM