So to do a very simplified use case, I have three components:
const ParentComponent = (props) => {
return(
<ChildComponentA ...variousPropsHere />
<ChildComponentB ...variousPropsHere />
}
ChildComponentA is an overlay that shows when a user clicks something, we'll call the value "value".
ChildComponentB doesn't need "value" at all. And in fact I want to prevent ChildComponentB from re-rendering based on the data change, because rendering ChildComponentB is extremely expensive, and it has no need of updating.
But ChildComponentA does need the value and needs to re-render based on "value" updating.
I have considered useContext, refs, useReducer, etc, but none of them are working quite how I want - useContext seems like it will update all components that subscribe to it - plus the state would still be managed in the parent, necessitating a re-render there too. Refs won't re-render ChildComponentA. useReducer also seems like it will cause parent re-render (and thus child re-renders). Memoization helps with the speed of ChildComponentB re-rendering, but it's still pretty slow.
At this point I'm leaning towards just using my global redux store, storing the value there, and clearing it out on component dismount. That would allow me to update the value from ChildComponentB, without subscribing ChildComponentB (or ParentComponent) to the value itself, preventing re-render in these very expensive components.
Is there a more elegant way to do this than the way I am describing?
I just really cannot have ChildComponentB re-render, but must have ChildComponentA re-render based on a value change.
CodePudding user response:
I really like this state management library called zustand. I think it can create a really concise and clean solution a lot of times. Using it you could create a store and share state between components without needing a context or make prop drilling, or share data via the parent component.
It is really fast and simple to use and can be really useful if you dont want to use something more complex like redux.
Here is its introduction: zustand getting started
CodePudding user response:
Instead of keeping value in Context or State of parent component, keep there callback from ChildComponentA and call it from ChildComponentB.
This way only sibling component will be rerendered.
Example:
const ChildComponentA = () => {
const context = useContext(SomeContextToStoreCallback)
useEffect(() => {
context.callback = (value) => {
// Do something expensive
}
return () => {
context.callback = undefined;
}
}, [])
// rest of the code....
}
const ChildComponentB = () => {
const context = useContext(SomeContextToStoreCallback)
const handleSomeEvent = (value) => {
context.callback?.(value)
}
// rest of code.....
}
This is only a pseudo code, but you've got an idea. Something similar is used in large libraries like mui-x