Reputation: 550
I have nested arrays in my props, and the user can re-order the second-level array by dragging and dropping column. I (using redux) make a shallow copy of getState's outer array, do the re-ordering (through re-assignment of array objects based on index), and return the new array to the state (using spread operator in my reducer). However, componentDidUpdate
is not called if this ordering is the first thing I do after page load. If I take other actions that update the props/state, and then attempt to re-order, the ordering works fine and componentDidUpdate
is called.
In the former situation, where ordering is the first thing I try to do after page load/refresh, the render function is hit (with the properly re-ordered props) but the DOM never updates, presumably because redux does not recognize a state change?
It just seems like some other props change (even if unrelated to arrays) "wakes up" redux or connect
and allows it to recognize changes.
Here's where I copy, dispatch and then release the updated state in the reducer:
in actionCreator method:
...
const newProjects = getState().tracker.projects.slice().map(p => {
if (p.innerArray) {
const from = p.innerArray[draggedId-1];
const to = p.innerArray[droppedId-1];
p.innerArray[draggedId - 1] = { ...to, order: draggedId };
p.innerArray[droppedId - 1] = { ...from, order: droppedId };
}
return p;
})
dispatch({ type: 'RECEIVE_FIELD_UPDATE', projects: newProjects, message: "Sorted" });
reducer:
case 'RECEIVE_FIELD_UPDATE':
return {
...state,
projects: action.projects,
message: action.message
}
As you can see, I'm not mutating state in the reducer or doing other anti-pattern things (as far as I'm aware).
FWIW, the "Sorted" value on message property seems to get through whether or not componentDidUpdate
is hit (I have a modal that pops up with the message to confirm).
Any pointers or related documentation would be helpful; I've been reading all I can find, including other StackOverflow posts, but to no avail.
UPDATE Solved the issue, it did have to do with redux not diff-ing the properties but not because of what I expected, read below if interested.
Upvotes: 0
Views: 1595
Reputation: 550
Figured this out, and per usual I was looking in the wrong place.
The issue was that my conditional check on page load to prevent re-loading of already stored data was preventing any dispatches from firing. When I looked in the reducer, the sub-arrays of the projects were identical after dragging, because the state had not been previously connected yet. I thought a hard refresh would cause a full re-load but apparently I need to read more about how redux stores data and how to refresh that.
Anyways, fixing this condition so that I get new data on page load fixed the issue and componentDidUpdate
is now being triggered consistently.
Upvotes: 1
Reputation: 885
When updating state in a reducer in an array format, I've had to spread state again in order for updates to happen and keep from mutating.
case 'RECEIVE_FIELD_UPDATE':
return {
...state,
projects: ...state, ...action.projects,
message: action.message
}
or...
case 'RECEIVE_FIELD_UPDATE':
return {
...state,
projects: [...state, ...action.projects],
message: action.message
}
Depending on the format. Hope that helps.
Upvotes: 0