So basically I am using google maps api, where when I click on a building it shows a Modal with somme information. The state of this modal is in Context and updated from click event on map. What happens is, when the state updates, it rerenders the whole Map again (making it zoom out) since the state is being updated from the Map component itself.
How do I do so that the context state gets updated but the map doesn’t rerender?
I tried using memo and useCallback, but since the props are getting updated (the context) it does rerender the map again.
2
Answers
To update the state in Context from a component without making that component rerender, you can make use of the
React.memo()
higher-order component and theuseContext()
hook.The
React.memo()
higher-order component is used to memoize a component and prevent it from re-rendering if its props don’t change. By default,React.memo()
uses a shallow comparison to compare props.The
useContext()
hook is used to access the state stored in the Context. When the state in the Context changes, it will trigger a re-render in any component that is consuming that state.To prevent the Map component from re-rendering when the state in the Context changes, you can wrap it in
React.memo()
and useuseContext()
to access the state from the Context. Here’s an example:In this example, the
Map
component is wrapped inReact.memo()
, which will prevent it from re-rendering if its props don’t change. TheuseContext()
hook is used to access themodalState
andupdateModalState
functions from theMyContext
Context.When the state in the Context changes, the
Map
component will not re-render because it is memoized. Instead, it will continue to display the same map with the same markers and click handlers. Only the modal state will be updated in the Context.If your Map uses the value from context that changes often, there is no way to prevent rerenders. If you do, then it wont work anymore
useContext(Context) makes your component to rerender if the value in the provider changes. Does not matter what you use from the context in the component, if you use useContext it will rerender. You can not prevent that, this is how context works. But there are techniques that you can use to stop rerenders if your component uses things from context that does not change often.
Create new component that uses your one, that you want to memoize. Call the context there. Pass it as prop to your component. use React.memo on your component. But you have to make sure that all the props you pass to your component are memoized.
Additionally you can use the second argument in the memo to exclude things that don’t keep their references between renders (not recommended if you don’t know what you are doing, it may lead to closure problems)
Then you have to use YourNewComponent instead of your component