Reputation: 31
We can prevent unnecessary calculations for useEffect with an empty array as the second argument in the hook:
// that will be calculated every single re-rendering
useEffect(() => {...some procedures...})
// that will be calculated only after the first render
useEffect(() => {...some procedures...}, [])
But, for the useContext hook we can't do like above, provide the second argument. Also, we can't wrap useContext by useCallback, useMemo. For instance, we have a component:
const someComponent = () => {
const contextValue = useContext(SomeContext);
const [inputValue, setInputValue] = useState('');
return (
<Fragment>
<input value={inputValue} onChange={onInputChange} />
<span>{contextValue}</span>
</Fragment>
)
The problem is that every single typing will launch re-rendering and we will have unnecessary useContext re-rendering each time. One of the decision is brake the component on two:
const WithContextDataComponent = () => {
const contextValue = useContext(SomeContext);
return <JustInputComponent contextValue={contextValue} />
const JustInputComponent = (props) => {
const [inputValue, setInputValue] = useState('');
return <input value={inputValue} onChange={onInputChange} />
So, now the problem is disappeared, but two components we have, though. And in the upper component instead <SomeComponent />
we should import <WithContextDataComponent />
, that a little bit ugly, I think.
Can I stop the unnecessary re-rendering for useContext without splitting into two components?
Upvotes: 0
Views: 446
Reputation: 31365
From React Hooks API Reference:
https://reactjs.org/docs/hooks-reference.html#usecontext
useContext
const value = useContext(MyContext);
Accepts a context object (the value returned from React.createContext) and returns the current context value for that context. The current context value is determined by the value prop of the nearest above the calling component in the tree.
When the nearest above the component updates, this Hook will trigger a rerender with the latest context value passed to that MyContext provider.
As you can see from the documentation, the useContext()
hook will only cause a re-render of your component if the values that it provides change at some point. Ans this is probably your intended behavior. Why would you need stale data in your context hook?
When your component re-render by itself, without changes in the context, the useContext()
line will simply give back the same values that it did on the previous render.
It seems that you're using the useContext()
hook the way it it meant to be used. I don't see anything wrong with it.
Upvotes: 1