Reactjs useMemo 钩子行为,如 componentDidMount

时间:2021-04-26 08:29:46

标签: reactjs react-hooks

我正在尝试将 useMemo 像 useEffect 与 componentDidMount 行为一起使用,但我的 useMemo 的行为就像 componentWillMount 一样,并且呈现不可阻挡。

代码如下:

useMemo(() => {
    console.log('rendered');
    fetch(`backend url`, {
      method: 'PUT',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        userId: userInf._id,
        fields: ['readers', 'followers', 'news', 'podcast', 'video'],
      }),
    })
      .then((res) => res.json())
      .then((res) => {
        setUserArticles(res.news);
      })
      .catch((err) => err);
  }, [userArticles]);

请问有什么建议吗?

1 个答案:

答案 0 :(得分:2)

问题

useMemo 钩子用于计算和记忆一个值。看起来你的钩子回调实际上正在更新 some 状态,并且这个状态或值也在钩子的依赖数组中声明,在更新和重新渲染后,它将再次运行钩子回调并更新状态。 .. 创建一个无限循环。

解决方案

如果您想在组件挂载时仅发出一次副作用,例如 componentDidMount,请使用带有空依赖项数组的 useEffect

useEffect(() => {
  console.log('rendered');
  fetch(`backend url`, {
    method: 'PUT',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      userId: userInf._id,
      fields: ['readers', 'followers', 'news', 'podcast', 'video'],
    }),
  })
    .then((res) => res.json())
    .then((res) => {
      setUserArticles(res.news);
    })
    .catch((err) => err);
}, []);

Conditionally firing an effect

<块引用>

如果你想运行一个效果并且只清理一次(在安装和 unmount),您可以传递一个空数组 ([]) 作为第二个参数。这 告诉 React 你的效果不依赖于来自 props 的任何值 或状态,所以它永远不需要重新运行。这不作为特殊处理 case — 它直接遵循依赖项数组始终的方式 有效。

如果传入一个空数组([]),则效果内部的 props 和 state 将始终具有它们的初始值。将 [] 作为第二个传递时 参数更接近熟悉的 componentDidMountcomponentWillUnmount 心智模型,通常有更好的解决方案 以避免过于频繁地重新运行效果。另外,不要忘记 React 推迟运行 useEffect 直到浏览器完成绘制之后,所以这样做 额外的工作不是问题。