我是React的新手,有一些非常简单的代码,表现得很奇怪(我认为)。
主应用程序从服务器获取博客帖子列表,然后通过道具将其传递到子组件,该子组件将列表发出去。默认情况下,我试图使帖子仅显示如标题的预览,并且每个帖子都将附加一个状态,以便我可以跟踪哪些帖子已完全显示或预览。
我的状态设置如下:
const [posts, setPosts] = useState([])
const [postFullView, setPostFullView] = useState([])
该列表最初呈现为空列表,因此未返回任何内容。数据提取完成后,它将重新渲染所有帖子。
我在子组件中为此使用useEffect:
useEffect(() => {
console.log('render') //Just to verify this got called
setPosts(props.posts) //Logs empty array 3 lines down,
//setPosts([4,5,6]) //Works fine, gets logged as [4,5,6]
console.log(props.posts) //Logs an array of 32 objects - so props is clearly not empty
console.log(posts) //Logs empty array as if setPosts did nothing, but logs [4,5,6] if I comment out setPosts(props.post) and use setPosts([4,5,6])
setPostFullView(posts.map(post => {return {id: post.id, view: false}}))
console.log(postFullView) //Will be empty since posts is empty
}, [props])
希望,我清楚地解释了我的困惑-我可以使用硬编码数组setState,但是传递props.posts不会做任何事情,即使它具有内容。
答案 0 :(得分:1)
您的代码没有任何问题,原因是console.log(posts)
抛出了空数组,这是因为setPosts(props.posts)
是异步调用而不是立即执行,但是告诉它应该使用新的状态值再次呈现它
有时候,就像在您的硬编码数组中一样,代码可以“正常”运行,但是不能保证,一定要在生产中以更快的速度执行代码
答案 1 :(得分:0)
是的,这没什么错,因为setState api是异步的,没有显示日志中的更改,但是代码运行正常,并且如果您需要检查状态,也可以使用React开发人员工具扩展程序浏览器来查看状态 https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en
答案 2 :(得分:0)
实际上,您的第一个问题是了解状态变化和ReactJS上的重新渲染。为什么不像下面这样在第一个渲染中不使用第一个初始状态:
const YourComponent = ({ posts: initialPosts }) => {
const [posts, setPosts] = useState(initialPosts);
此外,不需要第一行就可以在第二行初始化时使用它,就像这样:
const YourComponent = ({ posts: initialPosts }) => {
const [postFullView, setPostFullView] = useState(
({ id }) => ({ id, view: false }) // es6 arrow function with using restructuring assignment and returning the object
);
毕竟,当您使用useEffect
或其他钩子API时,请在依赖项中添加特定的内部状态或道具名称,而不能将所有道具都放置在依赖项数组中,这会导致成本降低并导致您的项目运行缓慢。