对于我的react-app / Express应用程序,我尝试使用useEffects
更新组件状态以在组件呈现时运行一次。在useEffect
中,我提取到快递服务器。
const Favorites = ({ user }) => {
const loggedIn = user.loginname === "" ? false : true;
const [favs, setFavs] = useState([]);
useEffect(() => {
if (loggedIn) {
fetch(`/user/favs/${user.loginname}`)
.then((resp) => resp.json())
.then((data) => {
console.log(data);
setFavs([...data]);
console.log(favs);
});
}
}, []);
return (
<div className="mt-d d-flex justify-content-center">
{loggedIn ? (
<FavoritesList favs={favs} />
) : (
<h3 className="my-2">Please login to use this feature</h3>
)}
</div>
);
};
我在第11行进行了fetch调用,并能够在第14行打印结果。然后尝试更新
组件状态使用setFavs
。我的问题是状态似乎没有更新,或者也许
有一些异步问题。
const FavoritesList = ({ favs, prop }) => {
const [data, setData] = useState([]);
useEffect(() => {
console.log(favs);
// favs.forEach(item => console.log(item))
}, []);
return <h5>Dummy component</h5>;
};
当我尝试在第16行打印fav或在将其传递到child(FavoritesList)组件中的fav时,我得到一个空数组。
答案 0 :(得分:1)
当我尝试在第16行打印fav或在将其传递到child(FavoritesList)组件中的fav时,我得到一个空数组。
您是对的,这是一个异步问题:您对setFavs
的调用是异步的,并且尚未在第16行设置favs
。调用setFavs
将导致您的用户界面重新-最终渲染。
您也不会在第35行的其他useEffect
中看到它,因为该useEffect
钩子也仅在第一个渲染([]
)上运行,因此该值不是在那里第一次渲染。要查看对favs
的所有更新,请尝试将其添加到依赖项数组(如[favs]
)或完全删除依赖项数组。
答案 1 :(得分:0)
将收藏夹列表上的useEffect
更改为:
useEffect(() => {
console.log(favs)
}, [favs])
这样,useEffect
将监视favs
道具中的任何更改。使用空数组意味着useEffect
仅在功能组件的第一个渲染中触发。这意味着它不会在任何道具更改中被触发。
答案 2 :(得分:0)
我认为以上两个答案可以使一切变得干净,这就是您的生命周期;
1 -> Favorites component initialized and rendered (state favs = [empty])
2 -> FavoritesList component initialized and rendered (prop favs = [empty])
3 -> FavoritesList useEffect called (console.log(favs) => [empty array])
4 -> Favorites useEffect called (state favs = [now has data])
5 -> FavoritesList component props is updated (prop favs = [has data]
(prop is updated but you didnt call console.log again, after update)
您会看到收藏夹列表 useEffect在收藏夹 useEffect之前调用,因此在favs没有数据时调用它。 因此,如果您在收藏夹列表组件的useEffect中将favs prop添加到数组,您将再走一步;
6 -> FavoritesList useEffect called again (console.log(favs) => [has data])
因为useEffect会查找该数组元素,并且如果其中一个元素更改,它将再次触发自身。
这是您的示例代码:codesandbox.io