I have a big component, inside I have 4 subcomponents, each 4 subcomponents have a couple of components each. Only two levels of components, but I still pass a lot of props and handlers and I have all the state in the top component:
const MyBigComp = () => {
const [a, setA] = useState(false);
const [b, setB] = useState([]);
const [c, setC] = useState(0);
const [d, setD] = useState(true);
const [e, setE] = useState({ f: [], g: [] });
// I have ~20 more useState hooks in here.
// Then I have a lot of handlers:
const toggleX = () => {
setA(prev => !prev);
}
const addY = () => {
setB(prev => ([...prev, { z: 1 }]));
}
// And I have more useEffects and other handlers in here also.
return (
<Comp1 a={a} toggleX={toggleX} /> // For simplicity I only pass two props but in reality there are like 10-12 props for each component.
<Comp2 b={b} addY={addY} />
<Comp3 c={c} toggleX={toggleX} />
<Comp4 d={d} e={e} addY={addY} />
);
}
My first thought would be to lower the state whenever possible, but every piece of state needs to be in the parent component because it’s used by a handler or shared to other components.
I thought of using Context but I don’t know if it’s the best solution here since prop drilling is not much of an issue since it’s only two levels down.
2
Answers
This sounds like a case for
useReducer
, which is an ergonomic way of dealing with complex state management in a single state object.Your code looks like it could be modeled roughly like this:
Which you can then use like this:
It’s a bit difficult to say what is the best option to you case because the context that you gave is too short, but I think you just need to use react’s ContextApi to reduce the amout of the useStates and avoid prop drilling.
StoreContext.js:
App.jsx:
MyBigComp.jsx:
I think that this is what you need for now, but of course, if you need to improve you code, you can use useReducer hook, for example, or even redux/zustand/jotai or other state manager library.
I hope I had help