设置状态不会改变对象的状态

时间:2021-04-28 13:04:57

标签: reactjs

我正在尝试使用设置状态设置一个对象,但是什么也没发生。

我将 blog 对象初始化为一个几乎为空的对象,然后我通过 setBlog 将其设置为一个新对象。

请注意,登录控制台时,我可以看到 foundBlog 对象,因此问题不存在。问题是在 blog 之后记录 setBlog 对象时,我看到的是初始对象,所以 setBlog 没有做任何事情。

我的问题是:在这种情况下使用 setBlog 的正确方法是什么?

import React, { useEffect, useState } from 'react';
import { RouteComponentProps, withRouter } from 'react-router';

import Blogs from '../../mock-data/draftBlogs.json';
import BlogCreation, { IBlogCreationProps } from './create-edit-blog/BlogCreation';

interface IBlogPageProps {

}

const blogArr = Blogs.blogs;

const BlogPage: React.FunctionComponent<IBlogPageProps & RouteComponentProps<any>> = (props) => {

  const [blog, setBlog] = useState<IBlogCreationProps>({
    id: 4,
    title: "",
    content: "",
    description: "",
    publisher: "",
    published: false
  });
  
  useEffect(() => {
    let number: number = props.match.params.number;
   
    const foundBlog = (blogArr.find(({id}) => id == number)) as IBlogCreationProps;
    console.log("foundBlog", foundBlog); // logs the expected result
    // code below is supposed to set the object to the new object, but it's not working
    setBlog({...blog,
      id: foundBlog.id,
      title: foundBlog.title,
      content: foundBlog.content,
      description: foundBlog.description,
      publisher: foundBlog.publisher,
      published: foundBlog.published}
      );
    console.log("blog", blog); // logs the initial object
  }, [props])
  return (
    <BlogCreation
      id={blog.id}
      title={blog.title}
      content={blog.content}
      description={blog.description}
      publisher={blog.publisher}
      published={blog.published}
    />
  );
};

export default withRouter(BlogPage);

编辑:

事实证明这是一个与依赖数组相关的问题,更改依赖修复了初始日志记录问题(没有看到正确的对象),但它增加了其他问题,我可以看到两个日志而不是一个。 无论如何,我的主要问题是用正确的道具渲染组件没有解决。

1 个答案:

答案 0 :(得分:0)

您的代码似乎有效。您在 console.log 中看不到更改的原因是 setState 是异步的。这个函数不会更新值,它告诉 React 你想要更新它,React 很快就会自己做。结果是状态不会立即重新分配,并且您的代码在更新之前记录状态。

但是,您可以将回调作为第二个参数传递给 setState,它将在更新完成后立即调用:setState(newValue, callback)

setBlog({...blog,
      id: foundBlog.id,
      title: foundBlog.title,
      content: foundBlog.content,
      description: foundBlog.description,
      publisher: foundBlog.publisher,
      published: foundBlog.published
}, () => console.log("blog", blog)); // this is called after the state
                                     // is effectively updated