reactjsreact-hooksreact-context

controlling React Context - caused rendering


I am using a react App, with a context holdling a wordlist. I have a child component of the context , which uses a context function which edits the current word (setting the wordlist). When I do that with useContext, it renders the child component (All of them!).

export default function EditWordlistElem({content,elemId}){
    const {editWordlist} = useWordlist(); // using context
    const {newValue,setNewValue} = useState(content); // holds edited value
    return (<div> 

                 {/* Some code for getting edited value*/}
                <button onClick={()=>editWordlist(newValue,elemId))>
                    Edit
                </button>
            </div>);
}

My point is, that i don't actually need the updated edit funciton every the whole time the child component is up, but only on editing (for exampmle on a button press).

However trying accessing the context conditionally, or inside a callback is illegal with react hooks.

From https://reactjs.org/docs/hooks-rules.html

Only Call Hooks at the Top Level

Don’t call Hooks inside loops, conditions, or nested functions.

How can i get the context value Only on a button click , so it won't render this component on every context change?


Solution

  • If your hook is subscribing with useContext to the WordList values, it will re-render every time the word list is updated. From there, any components that subscribe to that hook will also re-render, causing the whole child tree to re-render.

    One way to optimize that functionality is to use two Context providers. One to store the actual values in state, and one to store the dispatch/setter functions including editWordlist. Since the editWordlist reference should not change, you can call this function without subscribing to the values.

    See: https://kentcdodds.com/blog/how-to-optimize-your-context-value for a more detailed explanation of this pattern.

    Lastly, if you are using React 19, they have introduced the use function which can load a context value without following the rules of hooks.

    See: https://react.dev/reference/react/use