React js:同步运行具有常见问题的效果useEffect

问题描述

我设置了两个效果来实例化我的无状态反应组件中的一些值。但是,我似乎无法在第二个函数中访问第一个函数设置的数据。

从我的阅读来看,这些似乎是异步运行的,因此不能保证每个函数何时运行。 当具有共同关注点的效果依赖于彼此的效果时,如何让它们同步运行?或者,实际上是否有更好的做法来替换无状态 React 组件中的 constructor? >

相关代码

const [roadTiles,setRoadTiles] = useState([]);

...

useEffect(() => {
    populateRoadTiles(); // calls setRoadTiles() -- console.log shows roadTiles has been set
    populateRoadTileDivs(); // uses roadTiles -- roadTiles is still [] and causes index error
},[])

我四处寻找类似的问题,但大多数解决方案都归结为用户代码中的个别错误。希望这能更好地提炼问题。

编辑:

链接依赖项似乎是基于 Daniil's comment 和文档的方法

但是,我仍然遇到同样的问题。也许这是我在 populateRoadTiles 中的逻辑的问题(如下)。该文档似乎表明 set*() 函数也是异步的,因此在 populateRoadTiles 之后仍然未设置 roadTiles 是有道理的。

但是,使用新的依赖结构,最终会调用 populateRoadTileDivs。这似乎表明应该已经设置了roadTiles并触发了第二个效果

    const populateRoadTiles = () => {
        const newRoadTiles = new Array(height);
        for (let r = 0; r < height; r++) {
            newRoadTiles[r] = new Array(width);
        }
        for (let r = 0; r < height; r++) {
            for (let c = 0; c < width; c++) {
                newRoadTiles[r][c] = (
                    <RoadTile
                        onClick={() => getNeighbors(r,c)}
                        type={RoadTileType.EMPTY}
                    />
                );
            }
        }
        setRoadTiles(newRoadTiles);
        console.log(newRoadTiles); // populated array
        console.log(roadTiles); // []
    };

解决方法

每个 useEffect 有 [dependency] 或没有 [] === componentDidMount

React 在依赖改变后运行效果。

const [roadTiles,setRoadTiles] = useState([]);
const [roadTilesDivs,setRoadTilesDivs] = useState([]);

...

useEffect(() => {
    populateRoadTiles(); // calls setRoadTiles() -- console.log shows roadTiles has been set
},[])

useEffect(() => {
    populateRoadTileDivs(); // uses roadTiles -- roadTiles is still [] and causes index error
},[roadTiles]) // <- add dependency here

如果你想记录状态保持它可变

    setRoadTiles(newRoadTiles); 
    console.log(newRoadTiles); // not actual,but it will be correct 
    console.log(roadTiles); // [] actual but it's prematurely.
,

使用 useMemo 作为 Reactjs 试试这个

useMemo(() => {
    populateRoadTiles(); // calls setRoadTiles() -- console.log shows roadTiles has been set
    populateRoadTileDivs(); // uses roadTiles -- roadTiles is still [] and causes index error
},[])

API: https://reactjs.org/docs/hooks-reference.html#usememo

示例: https://www.robinwieruch.de/react-usememo-hook