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.
- Did you ever get a satisfactory answer? – Biaspoint Commented Jul 10, 2023 at 13:35
5 Answers
Reset to default 2Use 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.