最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React.useMemo does not work to prevent re-renders - Stack Overflow

programmeradmin3浏览0评论

I have the following simple ponent:

const Dashboard = () => {
  const [{ data, loading, hasError, errors }] = useApiCall(true)

  if (hasError) {
    return null
  }

  return (
    <Fragment>
      <ActivityFeedTitle>
      <ActivityFeed data={data} isLoading={loading} />
    </Fragment>
  )
}

export default Dashboard

I would like to prevent ALL re-renders of the ActivityFeedTitle ponent, so that it only renders once, on load. My understanding is that I should be able to use the React.useMemo hook with an empty dependencies array to achieve this. I changed by return to be:

return (
    <Fragment>
        {React.useMemo(() => <ActivityFeedTitle>, [])}
        <ActivityFeed data={data} isLoading={loading} />
    </Fragment>
)

As far as I'm concerned, this should prevent all re-renders of that ponent? However, the ActivityFeedTitle ponent still re-renders on every render of the Dashboard ponent.

What am I missing?

EDIT:

Using React.memo still causes the same issue. I tried memoizing my ActivityFeedTitle ponent as follows:

const Memo = React.memo(() => (
  <ActivityFeedTitle />
))

And then used it like this in my return:

return (
    <Fragment>
        {<Memo />}
        <ActivityFeed data={data} isLoading={loading} />
    </Fragment>
)

Same problem occurs. I also tried passing in () => false the following as the second argument of React.memo, but that also didn't work.

I have the following simple ponent:

const Dashboard = () => {
  const [{ data, loading, hasError, errors }] = useApiCall(true)

  if (hasError) {
    return null
  }

  return (
    <Fragment>
      <ActivityFeedTitle>
      <ActivityFeed data={data} isLoading={loading} />
    </Fragment>
  )
}

export default Dashboard

I would like to prevent ALL re-renders of the ActivityFeedTitle ponent, so that it only renders once, on load. My understanding is that I should be able to use the React.useMemo hook with an empty dependencies array to achieve this. I changed by return to be:

return (
    <Fragment>
        {React.useMemo(() => <ActivityFeedTitle>, [])}
        <ActivityFeed data={data} isLoading={loading} />
    </Fragment>
)

As far as I'm concerned, this should prevent all re-renders of that ponent? However, the ActivityFeedTitle ponent still re-renders on every render of the Dashboard ponent.

What am I missing?

EDIT:

Using React.memo still causes the same issue. I tried memoizing my ActivityFeedTitle ponent as follows:

const Memo = React.memo(() => (
  <ActivityFeedTitle />
))

And then used it like this in my return:

return (
    <Fragment>
        {<Memo />}
        <ActivityFeed data={data} isLoading={loading} />
    </Fragment>
)

Same problem occurs. I also tried passing in () => false the following as the second argument of React.memo, but that also didn't work.

Share Improve this question edited Oct 22, 2019 at 2:38 JavascriptLoser asked Oct 22, 2019 at 1:58 JavascriptLoserJavascriptLoser 1,9625 gold badges37 silver badges67 bronze badges 1
  • Did you ever get a satisfactory answer? – Biaspoint Commented Jul 10, 2023 at 13:35
Add a ment  | 

5 Answers 5

Reset to default 2

Use React.memo() instead to memoized ponents based on props.

React.memo(function ActivityFeedTitle(props) {
  return <span>{props.title}</span>
})

Take note:

This method only exists as a performance optimization. Do not rely on it to “prevent” a render, as this can lead to bugs.

You can use React.memo and use it where your define your ponent not where you are making an instance of the ponent, You can do this in your ActivityFeedTitle ponent as

const ActivityFeedTitle = React.memo(() => {
  return (
   //your return
  )
})

Hope it helps

The second argument passed to React.memo would need to return true in order to prevent a re-render. Rather than puting whether the ponent should update, it's determining whether the props being passed are equal.

Your usage of useMemo is incorrect.

From react hooks doc:

Pass a “create” function and an array of dependencies. useMemo will only repute the memoized value when one of the dependencies has changed. This optimization helps to avoid expensive calculations on every render.

If no array is provided, a new value will be puted on every render.

You need to use useMemo like useEffect here for putation of value rather than rendering the ponent.

React.memo

React.memo() is the one you are looking for. It prevents re-rendering unless the props change.

It's because rendering a parent causes it's children to re-render for the most part. The better optimization here would be to place your data fetching logic either in the ActivityFeed ponent or into a HOC that you wrap ActivityFeed in.

发布评论

评论列表(0)

  1. 暂无评论