React js: 运行 效果(useEffect) 同步关注共同点
React js: run effects (useEffect) with common concerns synchronously
我设置了两个效果来实例化我的无状态 React 组件中的一些值。但是,我似乎无法在我的第二个函数中访问我的第一个函数设置的数据。
根据我的阅读,这些似乎 运行 是异步的,因此不能保证每个函数何时会 运行。 当 运行 相互依赖时,如何同步获得与 运行 共同关注的效果? 或者,实际上是否有更好的做法来替换 constructor
一个无状态的 React 组件?
相关代码:
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
}, [])
我搜索了类似的问题,但大多数解决方案都归结为用户代码中的个别错误。希望这能更好地提炼问题。
编辑:
根据 和文档,链接依赖项似乎是可行的方法。
但是,我仍然运行遇到同样的问题。也许这是我在 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); // []
};
将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
每个 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.
我设置了两个效果来实例化我的无状态 React 组件中的一些值。但是,我似乎无法在我的第二个函数中访问我的第一个函数设置的数据。
根据我的阅读,这些似乎 运行 是异步的,因此不能保证每个函数何时会 运行。 当 运行 相互依赖时,如何同步获得与 运行 共同关注的效果? 或者,实际上是否有更好的做法来替换 constructor
一个无状态的 React 组件?
相关代码:
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
}, [])
我搜索了类似的问题,但大多数解决方案都归结为用户代码中的个别错误。希望这能更好地提炼问题。
编辑:
根据
但是,我仍然运行遇到同样的问题。也许这是我在 populateRoadTiles 中的逻辑问题(如下)。文档似乎表明 set*() 函数也是异步的,因此在 populateRoadTiles
.
但是,使用新的依赖结构,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); // []
};
将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
每个 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.