I'm working on a nested form in React where a user can have multiple forms, each form can have multiple sections, and each section can have multiple dropdowns. I'm facing an issue where removing a specific dropdown updates the state correctly but does not reflect the correct dropdown being removed in the UI.
I have these States
const [addConditions, setAddConditions] = useState([[]]);
const {formIndex} = useContext(FormContext);
const [addConditions, setAddConditions] = useState([[]]);
const { formIndex } = useContext(FormContext);
const [eventValues, setEventValues] = useState([{
// ...other properties
conditions: [{ locked: [] }],
// ...
}]);
To add a section
const addSection = () => {
setAddConditions(prev => [...prev, [""]])
}
To add a dropdown
const addDropdownToSection = (sectionIndex) => {
setAddConditions(prev => {
const updated = [...prev];
updated[sectionIndex].push("");
return updated;
});
}
I store dropdown values in eventValues
const handlePropertyInputChange = (outerIndex, innerIndex, stateType="locked", e) => {
setEventValues(prevValues => {
let updatedEvents = [...prevValues];
let updatedConditions = [...updatedEvents[formIndex].conditions];
if (!updatedConditions[outerIndex]) {
updatedConditions[outerIndex] = { locked: [] };
}
const { name, value } = extractValue(e);
updatedConditions[outerIndex][stateType][innerIndex] = {
...updatedConditions[outerIndex][stateType][innerIndex],
[name]: value,
};
updatedEvents[formIndex].conditions = updatedConditions;
return updatedEvents;
});
};
Problem arises when I have to remove a specific dropdown
const removePropertyFromCondition = (sectionIndex, propertyIndex) => {
setEventValues(prevValues => {
let updateEvents = makeDeepCopy(prevValues)
let updatedConditions = [...updateEvents[formIndex].conditions];
updatedConditions[sectionIndex].locked.splice(propertyIndex, 1);
updateEvents[formIndex].conditions = updatedConditions;
console.log({updateEvents})
return updateEvents
});
setAddConditions(prev => {
const updated = makeDeepCopy(prev)
updated[sectionIndex].splice(propertyIndex, 1);
return updated;
});
};
When invoking removePropertyFromCondition, the eventValues state is updated correctly (as seen in the console), but in the UI, it's always the last dropdown in the section that gets removed, not the one I intended. After this, any interaction with dropdown values results in the app crashing.
How can I ensure that the correct dropdown is removed in the UI?
I attempted to assign a unique identifier to each section to address the issue, but this approach did not resolve the problem.
Any help is appreciated, thanks
Issue was arising due to unstable keys. I was using array indexes as keys for the mapped
<div/>but they were changing when elements were being added or removed. I used UUID's as stable identifiers.