【问题标题】:Why won't react component rerender when state is updated?为什么状态更新时组件不会重新渲染?
【发布时间】:2020-11-04 12:00:25
【问题描述】:

我有一个 React 应用程序,我需要帮助来重新渲染一个组件。

该组件代表一个博客。它列出了从数据库中提取的所有博客。底部有一个用于添加新帖子的表格。当我添加一个新帖子时,我不仅将它发送到后端以保存到数据库中,而且还将它添加到前端的博客列表中,以便它立即显示在 UI 中。

这是我的代码:

submitHandler(event) {
        event.preventDefault();

        let formData = new FormData();
        formData.append('title', this.postTitleRef.current.value);
        formData.append('body', this.postBodyRef.current.value);
        if (this.state.file) {
            formData.append('image', this.state.file);
        }

        if (this.state.editPostId) {
            formData.append('postId', this.state.editPostId);
            const editPost = this.state.blogPosts.find(p => p.id === this.state.editPostId);
            if (editPost.filename) {
                formData.append('filename', editPost.filename);
            }
            axios.patch('/blogs', formData, {
                    headers: {
                        Authorization: this.state.accessToken,
                        'content-type': 'multipart/form-data'
                    }
                }).then(response => {
                    const existingPost = this.state.blogPosts.find(p => p.id === this.state.editPostId);
                    existingPost.title = this.postTitleRef.current.value;
                    existingPost.body = this.postBodyRef.current.value;
                    existingPost.updatedAt = response.data.updatedAt;
                    existingPost.filename = response.data.filename || existingPost.filename;
                    existingPost.imageUrl = response.data.imageUrl || existingPost.imageUrl;
                    this.state.blogPosts.sort((p1, p2) => p1.updatedAt > p2.updatedAt ? -1 : 1);
                    this.clearForm();
                }).catch(err => {
                    console.log('err=', err);
                });
        } else {
            axios.post('/blogs', formData, {
                headers: {
                    Authorization: this.state.accessToken,
                    'content-type': 'multipart/form-data'
                }
            }).then(response => {
                this.state.blogPosts.unshift({
                    id: response.data.id,
                    createdAt: response.data.createdAt,
                    updatedAt: response.data.createdAt,
                    filename: response.data.filename || null,
                    title: this.postTitleRef.current.value,
                    body: this.postBodyRef.current.value,
                    imageUrl: response.data.imageUrl || null
                });
                this.clearForm();
            }).catch(err => {
                console.log('err=', err);
            });
        }
    }

当我把控制台登录查看this.state.blogPosts的内容时,表明确实添加了新帖子。但是除非我刷新页面,否则新帖子不会显示在屏幕上。

这和我调用 event.preventDefault() 有什么关系吗?

这与我将新帖子添加到状态 (this.state.blogPosts) 中的数组而不是调用 setState(...) 的事实有关吗?

甚至 this.forceUpdate() 似乎都不起作用。

谁能看到我做错了什么?谢谢。

【问题讨论】:

    标签: reactjs state rerender


    【解决方案1】:

    这是因为 React 不知道你的状态正在更新。要让 React 知道,请使用 this.setState

    this.setState((state) => ({
      blogPosts: [{/*your new blog*/}, ...state.blogPosts]
    }));
    

    【讨论】:

    • 你会认为这样可以解决问题,但它仍然不起作用。
    【解决方案2】:

    再深入一点,我发现除了 kkesley 建议的之外,问题还在于我对 useMemo(...) 的使用。为了构建博客文章表,我使用了 react-table,它的构建是通过调用 render() 中的 createTable() 来完成的。该表的数据构建如下:

        for (var index = 0; index < props.posts.length; index++) {
            const post = props.posts[index];
            dataArray.push({
                titleCol: post.title,
                bodyCol: post.body,
                updatedAtCol: post.updatedAt,
                imageUrlCol: post.imageUrl[0]
            });
        }
        const data = React.useMemo(() => dataArray, []);
    

    ...props.posts 是传递给 react-table 组件的 state.blogPosts。

    问题是 useMemo 总是返回原始数据数组,它只包含 state.blogPosts 中的原始帖子。我更改了该行以包含 dataArray 作为依赖项:

    const data = React.useMemo(() => dataArray, [dataArray]);
    

    这解决了问题。

    【讨论】:

      猜你喜欢
      • 2019-06-17
      • 2018-06-05
      • 2023-03-09
      • 1970-01-01
      • 2021-05-19
      • 2022-01-26
      • 2019-02-27
      • 1970-01-01
      • 2020-08-14
      相关资源
      最近更新 更多