What is a good way in React to deal with web forms with interdependent state, where changes in one input element cause cascading, dynamic changes in other elements?
Here's one example: I'm building a React form with four react-select components (let's call them A/B/C/D) and I'm trying to wire them up so that changes in one Select will cause changes in one or more of the others.
For example:
- If the user changes
A, then reload the data inB. Try to maintain a similar selected option inBafter the data is loaded. "Similar" means that if the new data contains an option with the same name, even if the underlying object is different, then keep that named option selected inB. Otherwise clearB's selection. - If the user changes
B, then loadCwith a filtered subset ofA's data, with the selected option ofBcontrolling how the filtering works. Like above, if the new contents ofChave a same-named option (even if the underlying data is different) then keep it selected. Otherwise, clear the selection inC. - If the user changes
Aand there's a selection inB, and if nothing is currently selected inC, then make the selection ofCmatch the selected option ofA. - If the user changes
C(including if it's changed via changes cascading fromAor B!) then refresh the contents ofD, but like above try to keep the same-named label selected inD, even if the data underneath it has changed. Otherwise select the first option in the newly-populatedD.
I'm fairly comfortable building React apps with controlled components where the state machine is simple and dependencies are clear. But in this case, the dependency tree is complicated!
I've already pushed my state (contents of A-D and their selected options) up to a container component.
But I'm finding that doing this is like pulling a thread on a sweater. After I moved the state up to the top, now I need domain-specific logic to determine what to do with the state, and that logic (e.g. getting data & translating it into user-visible UI in each component) is currently encapsulated in lower-level components. For example, component A is responsible for loading A's data, B loads B's data, etc.
Do I also need to move that logic up to the top-level component? Or is there some other pattern that I should consider for this kind of complex, interdependent UI state?
If it matters, I'm using plain React without any context, state-management or forms libraries, etc. Just useState and react-select.