简体   繁体   English

Reactjs useMemo hook 行为,如 componentDidMount

[英]Reactjs useMemo hook behaviour like componentDidMount

I am trying to use useMemo like useEffect with componentDidMount behaviour but my useMemo is acting just like componentWillMount and is rendering unstoppably.我正在尝试使用 useMemo 之类的 useEffect 和 componentDidMount 行为,但我的 useMemo 的行为就像 componentWillMount 一样,并且呈现不可阻挡。

Here is the code:这是代码:

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]);

Any suggestions please?请问有什么建议吗?

Issue问题

The useMemo hook is intended for computing and memoizing a value. useMemo钩子用于计算和记忆值。 It appears your hook callback is actually updating some state, and this state or value is also declared in the hook'd dependency array, which after updating and rerendering, will run the hook callback again and update state... creating an infinite loop.看起来你的钩子回调实际上正在更新一些state,并且这个 state 或值也在钩子依赖数组中声明,在更新和重新渲染之后,将再次运行钩子回调并更新 Z9ED39E2EA93142EF573E...创建一个无限循环。

Solution解决方案

If you want to issue a side-effect only once when the component mounts, like componentDidMount , then use an useEffect with an empty dependency array.如果您只想在组件挂载时发出一次副作用,例如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 有条件地触发效果

If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array ( [] ) as a second argument.如果你想运行一个效果并且只清理一次(在挂载和卸载时),你可以传递一个空数组( [] )作为第二个参数。 This tells React that your effect doesn't depend on any values from props or state, so it never needs to re-run.这告诉 React 你的效果不依赖于 props 或 state 的任何值,所以它永远不需要重新运行。 This isn't handled as a special case — it follows directly from how the dependencies array always works.这不是作为特殊情况处理的——它直接遵循依赖项数组的工作方式。

If you pass an empty array ( [] ), the props and state inside the effect will always have their initial values.如果传递一个空数组( [] ),则效果内的道具和 state 将始终具有其初始值。 While passing [] as the second argument is closer to the familiar componentDidMount and componentWillUnmount mental model, there are usually better solutions to avoid re-running effects too often.虽然传递[]作为第二个参数更接近于熟悉的componentDidMountcomponentWillUnmount mental model,但通常有更好的解决方案来避免过于频繁地重新运行效果。 Also, don't forget that React defers running useEffect until after the browser has painted, so doing extra work is less of a problem.另外,不要忘记 React 会延迟运行useEffect直到浏览器绘制完成,所以做额外的工作不是问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM