React useState() 数组未在 useEffect() 中更新

React useState() array not updating inside useEffect()

提问人:Anmol Garg 提问时间:11/10/2023 更新时间:11/10/2023 访问量:84

问:

import { useState, useEffect } from "react";
import 'react-tabulator/lib/styles.css';
import { ReactTabulator } from 'react-tabulator'

export default function Project() {
    const [projects, setProjects] = useState([]);

    
    const [isLoading, setLoading] = useState(true);
    const projectListUri = '/api/projects';
    // const apiPath = process.env.REACT_SERVER_HOST + projectListUri;
    useEffect(() => {
        fetch("http://localhost:8000/api/projects")
            .then((response) => response.json())
            .then((data) => {
                console.log(data); // line 16
                setProjects(data);
                console.log(projects); //line 18
                setLoading(false);
            }).catch((error) => {
                console.log(error.message);
                setLoading(false);
            });
    }, []);

    return (
        <div>
            {isLoading ? (
                <p>Loading...</p>
            ) : (
                <ReactTabulator
                    data={projects}
                    autoColumns={true}
                    layout={"fitColumns"}
                />
            )}
        </div>
    );



}

以上是我在应用程序中运行的代码。我正在从后端服务器获取数据。获取数据正常。我可以看到在第 16 行正确登录的数据。但是第 18 行始终显示一个空数组。因此,制表器库正确地提供了 isLoading 常量更新。Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'slice').

我试过两者都不起作用。setProjects(...data); setProjects([data]); setProjects(...projects, ...data);

ReactJS 获取 制表器

评论

0赞 Andy Ray 11/10/2023
这回答了你的问题吗?useState set 方法不会立即反映更改
0赞 Anmol Garg 11/10/2023
@AndyRay确实如此。我现在明白useState是异步的。我该如何解决这个问题?
0赞 Jahedul Hoque 11/10/2023
@AnmolGarg 你的目的是什么?为什么在设置状态后需要立即进行项目?当前代码应正确呈现表。最初,您的数据将是一个空数组,但立即成功获取数据后,您当前的代码应该可以正常工作。
0赞 Anmol Garg 11/10/2023
@JahedulHoque我当前的代码不起作用。提供渲染。此错误来自制表器.jsUncaught (in promise) TypeError: Cannot read properties of undefined (reading 'slice').
0赞 Jahedul Hoque 11/10/2023
@AnmolGarg 然后,您还应该共享制表器.js代码。似乎问题就在那里。

答:

0赞 Akeel Ahmed Qureshi 11/10/2023 #1

若要解决此问题,可以使用另一个 useEffect 钩子来观察项目状态的变化,并相应地执行操作。 更新后的代码如下:

import { useState, useEffect } from "react";
import 'react-tabulator/lib/styles.css';
import { ReactTabulator } from 'react-tabulator';

export default function Project() {
    const [projects, setProjects] = useState([]);
    const [isLoading, setLoading] = useState(true);
    const projectListUri = '/api/projects';

    useEffect(() => {
        fetch("http://localhost:8000/api/projects")
            .then((response) => response.json())
            .then((data) => {
                setProjects(data);
                setLoading(false);
            })
            .catch((error) => {
                console.log(error.message);
                setLoading(false);
            });
    }, []);

//here's the modified code
    useEffect(() => {
        console.log(projects);
    }, [projects]); 

    return (
        <div>
            {isLoading ? (
                <p>Loading...</p>
            ) : (
                <ReactTabulator
                    data={projects}
                    autoColumns={true}
                    layout={"fitColumns"}
                />
            )}
        </div>
    );
}