Reputation: 597
I am thinking of using react hooks [useReducer, useContext] and context api in place of redux. Having said I want my state to be bit complex in structure. Lets see the structure be as
state = {
key1: true,
key2: {
key3: [],
key4: ''
}
}
The thing that I am clear with is both redux and context api allows me to create complex structure. And in case of react hooks usage I can very well use Provider, Consumer/useContext to let pass my store state value to all my components.
The thing that Redux gives me more is that if any specific key say, key4
, is updated then helps me not to re-render entire app tree using connect function from react-redux
. And this is my query.
How can we make react hooks and context api to not to re-render my entire app which is a major performance bug?
Upvotes: 3
Views: 3419
Reputation: 2069
I've alternative thoughts about this.
Instead of thinking that hook should or shouldn't completely replace Redux, And instead of using a context state with a giant complex data structure.
You might want to break it down into many little custom hooks. For example,
const { name, pageCount } = useBook();
const { content, setContent } = useBookPage(i);
This gives me some important benefits
Now because there are many hooks spread around components, There must be a single source of truth to share across these hooks somewhere. The question is how we could manage or inject the source of truth...
This is another issue and it depends.
You could use useRef
to provide the plain object as a datastore.
You could use indexedDB, Redux, etc.
In the project I'm working on, All the data are stored within the external module library, So instead of using Redux, useRef, I fetch everything from that library.
I do still use the Context.Provider
and useContext
to inject those data stores and dependencies into my little hooks.
IMO, useMemo
is hacky to solve this because the problem is you have a coupling of massive state managements in the first place.
Upvotes: 0
Reputation: 1
if you really want to replace Redux using hooks I suggest using the useReducer and useContext hooks, they are easy to understand and quite flexible, here is an article that compares Redux and React hooks and detail: https://www.framelessgrid.com/react-hooks-vs-redux-for-state-management-in-2021/
Upvotes: -1
Reputation: 44078
This is something you just cannot achieve with only react context. Of course, you can trick around with useMemo so that the direct children of your Provider do not rerender, but apart from that: everytime any property of your context value changes, all consumers of said context will rerender, no matter if they used that specific property or not. You cannot bail out of a context rerender for some children only.
This might change in the future once useContextSelector
is integrated in react, but for now, this is just standard React behaviour and there is no way around that.
You can find more on "context vs a real state management solution" in this article.
For now, if you just want to reduce boilerplate it is probably just better to read up on modern redux or to look into other full-fledged state management libraries like mobx or recoil. But you won't get there with context alone without fully reimplementing one of those - and where's the point in that?
Upvotes: 6
Reputation: 1349
Re-rendering component tree is something react manages well. Both redux and context api update component state which leads to a re-render. In terms of performance, if you are looking for a way to manage not necessary re-renders I suggest you have a look at a few useful hooks, useMemo
, useCallback
, and React.memo
.
With these three hooks, you are able to prevent child components from re-rendering, if parent is updated.
const Parent = () => {
const [childAState, setChildAState] = useState();
useEffect(() => {
setChildAState('Child A Updated');
}, []);
return (
<ChildA childAState={childAState}/>
<ChildB />
);
};
const ChildA = () => React.memo((props) => {
return <h1>Child A</h1>
});
const ChildB = () => React.memo((props) => {
return <h1>Child B</h1>
});
In the above example, ChildB
wont re-render if a state in Parent
does change and leads to an update in ChildA
.
For further reading: React.memo
Upvotes: 0