React Hooks,状态未在useEffect中从获取中更新

时间:2020-08-09 01:01:34

标签: javascript reactjs fetch use-effect use-state

对于我的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时,我得到一个空数组。

3 个答案:

答案 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