反应setState()不在某些项目上设置状态

时间:2020-05-11 17:46:12

标签: javascript reactjs

我是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不会做任何事情,即使它具有内容。

3 个答案:

答案 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时,请在依赖项中添加特定的内部状态或道具名称,而不能将所有道具都放置在依赖项数组中,这会导致成本降低并导致您的项目运行缓慢。

相关问题