I have a state declaration in my application that holds an array of information and can be updated by a form nested within a sub-component.
I'm using useStates callback syntax in order to update the data, but for some reason, despite the callback running and the state changing, it won't be updated.
This can be confirmed when checking a state change in useEffect; it won't output any changes with a console.log. However, inside the callback itself, the console.log will work every time (so clearly the callback is running).
This is a simplified layout of what I'm doing:
const MainContext = createContext();
const Parent = () => {
const [data, setData] = useState([]);
const updateData = (index, field, value) => {
// This just updates (or initialises) an object at the specified index.
setData(previousState => {
let candidates = previousState;
let candidate = candidates[index];
if(typeof candidate !== "object"){
candidate = {};
}
candidate[field] = value;
candidates[index] = candidate;
// This will run every time, and return the correct result:
// [{
// example: value
// }]
console.log(candidates);
return candidates;
});
};
useEffect(() => {
console.log(data); // This will not run whenever the field is updated.
}, [data]);
return (
<MainContext.Provider value={{
dispatch: {
updateData
}
}}>
<Child />
</MainContext.Provider>
);
};
// Whenever a user enters data inside this components input, it should push a change
// via the dispatch.updateData method and update the array in the parent component.
const Child = () => {
const testIndex = 1;
return (
<MainContext.Consumer>{({ dispatch }) => (
<input
name="example"
placeholder="Example Field"
onChange={evt => dispatch.updateData(
testIndex,
evt.target.name,
evt.target.value
)} />
)}</MainContext.Consumer>
);
};
So, what's going on here? It appears the state is being set correctly, and even if I wrap the updateData method into a useCallback with the deps set to the state hook, it will still fail to console out in the useEffect.