【问题标题】:React Hooks, state not updating from fetch within useEffectReact Hooks,状态未从 useEffect 中的 fetch 更新
【发布时间】:2020-11-28 22:57:47
【问题描述】:

对于我的 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 行打印 favs 或在它被传递到的子 (FavoritesList) 组件中打印 favs 时,我得到一个空数组。

【问题讨论】:

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


    【解决方案1】:

    当我尝试在第 16 行打印 favs 或在传递给它的子 (FavoritesList) 组件中打印 favs 时,我得到一个空数组。

    你说得对,这是一个异步问题:你对 setFavs 的调用是异步的,favs 尚未在第 16 行设置。调用 setFavs 最终会导致你的 UI 重新渲染。

    你也不会在第 35 行的其他 useEffect 中看到它,因为 useEffect 钩子也只在第一次渲染时运行 ([]),所以在第一次渲染时还没有这个值。要查看对 favs 的所有更新,请尝试将其添加到依赖项数组(如 [favs])或完全删除依赖项数组。

    【讨论】:

      【解决方案2】:

      FavoritesList上的useEffect更改为:

      useEffect(() => {
      console.log(favs)
      }, [favs])
      

      这样useEffect 将监视favs 属性的任何变化。使用空数组意味着useEffect 只会在功能组件的第一次渲染中触发。这意味着它不会在任何道具更改中触发。

      【讨论】:

        【解决方案3】:

        我认为以上两个答案让一切都变得干净了,这是你的生命周期;

        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)
        

        如您所见,FavoritesList useEffect 在 Favorites useEffect 之前调用,所以它在 favs 没有数据时调用。 所以如果你在FavoritesList组件的useEffect中将favs prop添加到数组中,你就会多一步;

        6 -> FavoritesList useEffect called again (console.log(favs) => [has data])
        

        因为 useEffect 会查找该数组元素,如果其中一个元素发生更改,它将再次触发自身。

        这是您的代码和工作示例:codesandbox.io

        【讨论】:

          猜你喜欢
          • 2021-02-09
          • 2019-08-08
          • 2020-10-26
          • 2021-06-29
          • 1970-01-01
          • 1970-01-01
          • 2022-11-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多