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.