简体   繁体   中英

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.

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. 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.

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.

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. 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. 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. Also, don't forget that React defers running useEffect until after the browser has painted, so doing extra work is less of a problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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