From @LindaPaiste's answer:
When changing a value that is not the last in the path, you need to clear all subsequent selections because they were based on a different path.
That's the key to solving your problem! You have to somehow blow away and forget everything bellow the selection box whose value you are currently changing.
React was designed around the "blow away and forget" principle. Note also that The Data Flows Down. With that in mind, your task should be fairly easy to complete and while Linda's solution seems to work, it is perhaps not as simple as it could be.
What if we could have a special component that (1) accepts a sub-tree of your data, (2) renders its 1st level children as a selection box dropdown and then (3) repeats the process recursively? Something like this:
<RecursiveComponent subTree={DATA_SAMPLE} {/*maybe some other props*/}/>
When we think of recursion, we have to think of terminal conditions. In our case, this happens when the sub-tree is a primitive type (i.e. not an object ({}) or an array ([])).
Every RecursiveComponent has to:
- render the selection menu dropdown, containing all the 1st level children of the sub-tree
- render the nested
RecursiveComponent, based on props.subTree[selection]
- handle user interaction
Something like this:
import { MenuItem, Select } from "@material-ui/core";
import { useState } from "react";
function RecursiveComponent(props) {
const [selection, setSelection] = useState(props.currentSelection);
const handleChange = (event) => {
setSelection(event.target.value);
};
return (
<>
<Select variant="outlined" value={selection} onChange={handleChange}>
{Object.keys(props.subTree).map((key) => (
<MenuItem value={key}>{key}</MenuItem>
))}
</Select>
<div /> {/* forces a line break between selection boxes */}
{props.subTree[selection] !== Object(props.subTree[selection]) ? (
<></>
) : (
<RecursiveComponent
subTree={props.subTree[selection]}
currentSelection=""
/>
)}
</>
);
}
export default RecursiveComponent;
This is how you can use RecursiveComponent in your project by editing index.js:
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import { DATA_SAMPLE } from "./DataSample";
import RecursiveComponent from "./RecursiveComponent";
const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<RecursiveComponent subTree={DATA_SAMPLE} currentSelection="" />
</StrictMode>,
rootElement
);
processfunction as I don't quite get why you are looking atitem[1]. I'll see if I can fix this and write an answer.item[1]Personally I would manage the path as an array and render the individual selects based on that. When we update the path value at index2for example, we need to clear everything after that in the path. Is it cool if I write that method as an answer or do you want me to figure out what's going wrong in the current approach?