I have a problem with my InitialState with an error hidden somewhere. When I keep my InitialState in an array all these things work (* NOTES.TS is an array of objects). But when I try to make it an object, it doesn't seem to work at all. Can't find where's the issue...
const INITIAL_STATE: any[] = [...NOTES];
export const reducer = (state: any[] = INITIAL_STATE, action: any) => {
switch (action.type) {
case UPDATE_NOTE: {
return state.map((note) =>
note.id === action.payload.id
? {
...note,
status: "ARCHIVED",
}
: note
);
}
case CREATE_NOTE: {
return state.concat([
{
description: 'jj',
id: 12,
status: NOTE_STATUS.ACTIVE,
timestamp: CURRENT_DATE,
images: [],
username: "John Smith",
},
]);
}
default:
return state;
}
};
export default reducer;
and my filters in the selectors:
const globalSelector = (state: any) => state.notes;
export const selectCurrentNotes = createSelector(globalSelector, (notes) => {
return notes.filter((p: any) => p.status === NOTE_STATUS.ACTIVE);
});
But I needed to add more stuff to the InitialState, so I decided to make it an object and literally nothing works. Why?
const INITIAL_STATE: any = {
all: [...NOTES],
description: '',
images: []
};
export const reducer = (state: any = INITIAL_STATE, action: any) => {
switch (action.type) {
case UPDATE_NOTE: {
return state.all.map((note) =>
note.id === action.payload.id
? {
...note,
status: "ARCHIVED",
}
: note
);
}
case CREATE_NOTE: {
return state.all.concat([
{
description: 'jj',
id: 12,
status: NOTE_STATUS.ACTIVE,
timestamp: CURRENT_DATE,
images: [],
username: "John Smith",
},
]);
}
default:
return state;
}
};
export default reducer;
and my filters in the selectors:
const globalSelector = (state: any) => state.notes.all;
export const selectCurrentNotes = createSelector(globalSelector, (notes) => {
return notes.filter((p: any) => p.status === NOTE_STATUS.ACTIVE);
});
EDIT: First error concerns filters:
TypeError: undefined is not an object (evaluating 'notes.filter')
EDIT 2: notes
in filters are the name of the reducer, stored with the other ones in the global store.
const reducers = combineReducers({ favourites, notes, notifications, });
CodePudding user response:
Because in your reducer you do return state.all.map
which will overwrite the object state with the mapped array of notes.
You need to do
export const reducer = (state: any = INITIAL_STATE, action: any) => {
switch (action.type) {
case UPDATE_NOTE: {
return {
...state,
all: state.all.map((note) =>
note.id === action.payload.id
? {
...note,
status: "ARCHIVED",
}
: note
)};
}
case CREATE_NOTE: {
return {
...state,
all: state.all.concat([
{
description: 'jj',
id: 12,
status: NOTE_STATUS.ACTIVE,
timestamp: CURRENT_DATE,
images: [],
username: "John Smith",
},
])
};
}
default:
return state;
}
};
CodePudding user response:
Your reducer is returning different types which I don't think is what you want. For example:
return state.all.map((note) =>
note.id === action.payload.id
? {
...note,
status: "ARCHIVED",
}
: note
);
This is just returning the updated all
property of your state. Instead, you probably want:
const newAll = state.all.map((note) =>
note.id === action.payload.id
? {
...note,
status: "ARCHIVED",
}
: note
);
return {...state, all: newAll };
You'll need to fix this for all parts of your reducer to make sure you're returning the full state each time.