[英]Frontend not updating when using useState
So I have this blog application where I have to sort the blogs depending on the number of likes it has.所以我有这个博客应用程序,我必须根据喜欢的数量对博客进行排序。 This works fine when I first log in the app to see the blogs and also whenever I refresh the page.
当我第一次登录应用程序查看博客时,以及每当我刷新页面时,这都很好用。 More specifically, when I first log into the app and when I refresh the page everything is/gets sorted.
更具体地说,当我第一次登录应用程序并刷新页面时,所有内容都已排序。 Is there anyway to update/sort the blog list on the fronted without refreshing the page?
有没有办法在不刷新页面的情况下更新/排序前面的博客列表?
import { useState, useEffect } from 'react'
import Blog from './components/Blog'
import Login from './components/Login'
import CreateBlog from './components/CreateBlog'
import blogService from './services/blogs'
import loginService from './services/login'
import './app.css';
const App = () => {
const [blogs, setBlogs] = useState([]) // Unsorted array
const [user, setUser] = useState(null)
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [errorMsg, setErrorMsg] = useState('')
const [msg, setMsg] = useState('')
const [sortedArray, setSortedArray] = useState(null) //This sorts the original blog array
const [visibility, setVisibility] = useState(false)
useEffect( () => {
if(user != null){
setBlogs(user.blog)
setSortedArray(user.blog.sort((a,b) => parseInt(b.likes) - parseInt(a.likes)))
}
console.log("blogs is", blogs)
}, [user,sortedArray])
useEffect(() => {
const loggedInUser = window.localStorage.getItem('loggedBlogUser')
console.log("loggedInUser is", loggedInUser)
if(loggedInUser){
const user = JSON.parse(loggedInUser)
blogService.setToken(user.token)
console.log("user is", user)
setUser(user)
}
else{
console.log("Error here,", JSON.parse(loggedInUser))
}
},[])
const handleLogin = async (event) => {
event.preventDefault()
console.log("Logging in,", username, password)
try {
const user = await loginService({username, password})
setBlogs(user.blog)
setSortedArray(user.blog.sort((a,b) => parseInt(b.likes) - parseInt(a.likes)))
blogService.setToken(user.token)
window.localStorage.setItem('loggedBlogUser', JSON.stringify(user))
setUser(user)
setUsername('')
setPassword('')
}
catch(error){
setErrorMsg('Wrong username or password')
setTimeout(() => {
setErrorMsg('')
},3000)
}
}
const handleLogout = () => {
window.localStorage.removeItem('loggedBlogUser')
setUser(null)
setBlogs([])
setSortedArray([])
}
const addNewBlog = async (blogObject) => {
try {
const result = await blogService.createBlog(blogObject)
const result2 = await blogService.getUserBlogs(result.blog.slice(-1)[0])
user.blog = user.blog.concat(result2)
window.localStorage.setItem('loggedBlogUser', JSON.stringify(user))
setBlogs(user.blog)
setSortedArray(user.blog.sort((a,b) => parseInt(b.likes) - parseInt(a.likes)))
console.log("USER USER USER IS", user)
setVisibility(false)
setMsg(`a new blog ${blogObject.title} by ${user.name} added`)
setTimeout(() => {
setMsg('')
},3000)
}
catch(error){
console.log("error adding new blog", error)
}
}
return (
<div>
<h2>blogs</h2>
{msg !== '' && <h1 className='successMsg-container'>{msg}</h1>}
{errorMsg !== '' && <h1 className='errorMsg-container'>{errorMsg}</h1>}
{user == null &&
<Login
handleLogin={handleLogin}
setUsername={setUsername}
setPassword={setPassword}
username={username}
password={password}>
</Login>
}
{user != null && <div className="notes">
<p>{user.name} logged in <button onClick={handleLogout}>logout</button></p>
</div>}
{user != null &&
<CreateBlog
addNewBlog={addNewBlog}
visibility={visibility}
setVisibility={setVisibility}>
</CreateBlog>
}
{sortedArray !== null && sortedArray.map(blog =>
<Blog key={blog.id} blog={blog} setBlogs={setBlogs} setSortedArray={setSortedArray} user={user} />
)}
</div>
)
}
export default App
Blog code博客代码
import blogService from "../services/blogs"
const Blog = ({blog,user,setBlogs,setSortedArray}) => {
const [view, setView] = useState(false)
const [likeCount, setLikeCount] = useState(0)
const hideWhenVisible = {display: view ? 'none' : ''}
const showWhenVisible = {display: view ? '': 'none'}
const handleLikeClick = async (blog) => {
const id = blog.id
const actualBlog = await blogService.getUserBlogs(id)
try {
const updatedBlog = {
user: [blog.user[0]],
likes: actualBlog.likes + 1,
author: blog.author,
id: actualBlog.id,
title: blog.title,
url: blog.url
}
setLikeCount(updatedBlog.likes)
var elementPos = user.blog.map(ranBlog => {return ranBlog.id}).indexOf(blog.id)
user.blog[elementPos] = updatedBlog
window.localStorage.setItem('loggedBlogUser', JSON.stringify(user))
const result = await blogService.updateBlog(updatedBlog,id)
}
catch(error){
console.log("error liking blog")
}
}
return (
<div className="blog-container">
{blog.title}
<button onClick={() => setView(true)} style={hideWhenVisible}>view</button>
<button onClick={() => setView(false)} style={showWhenVisible}>hide</button>
{view && <div className="expanded-view-container">
<li className="extra-blog-info">
<ul>{blog.url}</ul>
{likeCount === 0 && <ul>likes: {blog.likes} <button onClick={() => handleLikeClick(blog)}>like</button></ul>}
{likeCount !== 0 && <ul>likes: {likeCount} <button onClick={() => handleLikeClick(blog)}>like</button></ul>}
<ul>{blog.author}</ul>
<ul>{blog.id}</ul>
</li>
</div>}
</div>
);
}
export default Blog;
From your code of Blog
component, I have seen that you haven't called setBlogs
and setSortedArray
which update blog states from App
.从您的
Blog
组件代码中,我看到您没有调用setBlogs
和setSortedArray
从App
更新博客状态。
I'd propose you should have another callback function called afterLikeClicked
in Blog
to update blogs
state which will make UI re-rendered.我建议你应该有另一个回调 function 在
Blog
中调用afterLikeClicked
来更新blogs
state 这将使 UI 重新呈现。
import blogService from "../services/blogs"
const Blog = ({blog, user, afterLikeClicked}) => {
const [view, setView] = useState(false)
const [likeCount, setLikeCount] = useState(0)
const hideWhenVisible = {display: view ? 'none' : ''}
const showWhenVisible = {display: view ? '': 'none'}
const handleLikeClick = async (blog) => {
const id = blog.id
const actualBlog = await blogService.getUserBlogs(id)
try {
const updatedBlog = {
user: [blog.user[0]],
likes: actualBlog.likes + 1,
author: blog.author,
id: actualBlog.id,
title: blog.title,
url: blog.url
}
setLikeCount(updatedBlog.likes)
//The change is here
afterLikeClicked(updatedBlog)
var elementPos = user.blog.map(ranBlog => {return ranBlog.id}).indexOf(blog.id)
user.blog[elementPos] = updatedBlog
window.localStorage.setItem('loggedBlogUser', JSON.stringify(user))
const result = await blogService.updateBlog(updatedBlog,id)
}
catch(error){
console.log("error liking blog")
}
}
return (
<div className="blog-container">
{blog.title}
<button onClick={() => setView(true)} style={hideWhenVisible}>view</button>
<button onClick={() => setView(false)} style={showWhenVisible}>hide</button>
{view && <div className="expanded-view-container">
<li className="extra-blog-info">
<ul>{blog.url}</ul>
{likeCount === 0 && <ul>likes: {blog.likes} <button onClick={() => handleLikeClick(blog)}>like</button></ul>}
{likeCount !== 0 && <ul>likes: {likeCount} <button onClick={() => handleLikeClick(blog)}>like</button></ul>}
<ul>{blog.author}</ul>
<ul>{blog.id}</ul>
</li>
</div>}
</div>
);
}
export default Blog;
And then update App
accordingly然后相应地更新
App
import { useState, useEffect } from 'react'
import Blog from './components/Blog'
import Login from './components/Login'
import CreateBlog from './components/CreateBlog'
import blogService from './services/blogs'
import loginService from './services/login'
import './app.css';
const App = () => {
const [blogs, setBlogs] = useState([]) // Unsorted array
const [user, setUser] = useState(null)
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [errorMsg, setErrorMsg] = useState('')
const [msg, setMsg] = useState('')
const [sortedArray, setSortedArray] = useState(null) //This sorts the original blog array
const [visibility, setVisibility] = useState(false)
useEffect( () => {
if(user != null){
setBlogs(user.blog)
setSortedArray(user.blog.sort((a,b) => parseInt(b.likes) - parseInt(a.likes)))
}
console.log("blogs is", blogs)
}, [user,sortedArray])
useEffect(() => {
const loggedInUser = window.localStorage.getItem('loggedBlogUser')
console.log("loggedInUser is", loggedInUser)
if(loggedInUser){
const user = JSON.parse(loggedInUser)
blogService.setToken(user.token)
console.log("user is", user)
setUser(user)
}
else{
console.log("Error here,", JSON.parse(loggedInUser))
}
},[])
const handleLogin = async (event) => {
event.preventDefault()
console.log("Logging in,", username, password)
try {
const user = await loginService({username, password})
setBlogs(user.blog)
setSortedArray(user.blog.sort((a,b) => parseInt(b.likes) - parseInt(a.likes)))
blogService.setToken(user.token)
window.localStorage.setItem('loggedBlogUser', JSON.stringify(user))
setUser(user)
setUsername('')
setPassword('')
}
catch(error){
setErrorMsg('Wrong username or password')
setTimeout(() => {
setErrorMsg('')
},3000)
}
}
const handleLogout = () => {
window.localStorage.removeItem('loggedBlogUser')
setUser(null)
setBlogs([])
setSortedArray([])
}
const addNewBlog = async (blogObject) => {
try {
const result = await blogService.createBlog(blogObject)
const result2 = await blogService.getUserBlogs(result.blog.slice(-1)[0])
user.blog = user.blog.concat(result2)
window.localStorage.setItem('loggedBlogUser', JSON.stringify(user))
setBlogs(user.blog)
setSortedArray(user.blog.sort((a,b) => parseInt(b.likes) - parseInt(a.likes)))
console.log("USER USER USER IS", user)
setVisibility(false)
setMsg(`a new blog ${blogObject.title} by ${user.name} added`)
setTimeout(() => {
setMsg('')
},3000)
}
catch(error){
console.log("error adding new blog", error)
}
}
return (
<div>
<h2>blogs</h2>
{msg !== '' && <h1 className='successMsg-container'>{msg}</h1>}
{errorMsg !== '' && <h1 className='errorMsg-container'>{errorMsg}</h1>}
{user == null &&
<Login
handleLogin={handleLogin}
setUsername={setUsername}
setPassword={setPassword}
username={username}
password={password}>
</Login>
}
{user != null && <div className="notes">
<p>{user.name} logged in <button onClick={handleLogout}>logout</button></p>
</div>}
{user != null &&
<CreateBlog
addNewBlog={addNewBlog}
visibility={visibility}
setVisibility={setVisibility}>
</CreateBlog>
}
{sortedArray !== null && sortedArray.map(blog =>
<Blog key={blog.id} blog={blog} afterLikeClicked={(updatedBlog) => {
const updatedBlogs = blogs.map((blog) => blog.id === updatedBlog.id ? updatedBlog : blog)
//update original blogs
setBlogs(updatedBlogs)
//update sorted blogs
setSortedArray(updatedBlogs.sort((a,b) => parseInt(b.likes) - parseInt(a.likes)))
}} user={user} />
)}
</div>
)
}
export default App
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.