skip to Main Content

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


  1. 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 the useContext() 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 use useContext() to access the state from the Context. Here’s an example:

    import React, { useContext } from 'react';
    import MyContext from './MyContext';
    
    const Map = React.memo(() => {
      const { modalState, updateModalState } = useContext(MyContext);
    
      // Render map with markers and click handlers
    
      return (
        <div>
          {/* Render map */}
          {/* Render markers */}
          {/* Click handlers */}
        </div>
      );
    });
    
    export default Map;
    

    In this example, the Map component is wrapped in React.memo(), which will prevent it from re-rendering if its props don’t change. The useContext() hook is used to access the modalState and updateModalState functions from the MyContext 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.

    Login or Signup to reply.
  2. 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)

    const YourComponent = React.memo(({someContextValue}) => ...)
    const YourNewComponent = () => {
       const {someContextValue} = useContext(SomeContext)
       // here someContextValue is a thing that does not change its value often
       return <YourComponent someContextValue={someContextValue} />
    }
    

    Then you have to use YourNewComponent instead of your component

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search