Reputation: 375
I have been trying to add a new item to my initial state with plain JS without using any utility library and it seems it's very complex. Here the structure of my initial state:
const initialState = {
isLoading: false,
events: [
{
year: 2021,
place: [
{ id: 1, name: "BD" },
{ id: 1, name: "BD Test" }
]
},
{ year: 2020,
place: [
{ id: 2, name: "AMS" },
{ id: 1, name: "AMS TEST" }
]
}
]
};
I want to add a new property to the matched item so that the state will modify like that:
const initialState = {
isLoading: false,
events: [
{
year: 2021,
place: [{ id: 1, name: "BD", newProp:"NewValue" },
{ id: 1, name: "BD Test" }
]
},
{ year: 2020,
place: [
{ id: 2, name: "AMS" },
{ id: 1, name: "AMS TEST" }
] }
]
}; In my reducer,I have tried:
case actionType.TOGGLE_INFO:
return {
...state,
events: state.events.map((x) => x.place[0].id === action.id
? { ...x, place: [{ ...x.place[0], newProp: "new Value"}] }
: x),
};
That code updates the value in the state but then it only displays one item (place) from the events. Is there any way, I can still display all the events and update the selected place(by adding the new property) inside an event. I have been trying to fix it for a while now. so, any bits of help would be highly appreciated. Thanks in advance. My reducer so far:
const initialState = {
isLoading: false,
events: [
{
year: 2021,
place: [{ id: 1, name: "BD" }, { id: 1, name: "BD Test" }]
},
{ year: 2020,
place: [{ id: 2, name: "AMS" }, { id: 1, name: "AMS TEST" }] }
]
};
const commonReducer = (state = initialState, action = {}) => {
switch (action.type) {
case "FETCH_EVENTS":
return {
...state
};
case "TOGGLE_INFO":
console.log(state.events);
return {
...state,
events: state.events[0].map(event =>
event.id === action.id
? { ...event, place: [{ ...event.place[0], isTouched: true }] }
: event
)
};
default:
return state;
}
};
export default commonReducer;
Upvotes: 0
Views: 63
Reputation: 351
I'm having a hard time understanding what you are trying to achieve but I'll try to help you anyway.
It'll be easier if you can pass the year also because of the way your data is structured but let's assume you can't:
return {
...state,
events: state.events.map(event => {
if(event.place.find(x => x.id === action.id)) {
return {
...event,
place: [...event.place, {newProp: "newValue"}]
}
} else {
return event
}
})
}
I Hope that helps but if not I would like you to show me the before and after of what you are trying to achieve.
Update:
Initial State(you had duplicate keys so I changed it):
const initialState = {
isLoading: false,
events: [
{
year: 2021,
place: [{ id: 1, name: "BD" }, { id: 2, name: "BD Test" }]
},
{ year: 2020, place: [{ id: 3, name: "AMS" }, { id: 4, name: "AMS TEST" }] }
]
};
The Reducer:
const commonReducer = (state = initialState, action = {}) => {
switch (action.type) {
case "UpdateEvents":
return {
...state
};
case "UpdatePlace":
console.log(state.events);
return {
...state,
events: state.events.map(event => {
const place = event.place.find(x => x.id === action.id);
if (place) {
return {
...event,
place: event.place.map(x => {
if (x.id === action.id) {
return { ...x, isTouched: true };
} else {
return x;
}
})
};
} else {
return event;
}
})
};
default:
return state;
}
};
export default commonReducer;
Place.js
:
return (
<div>
ID: { props.place.id }
Name: { props.place.name }
<div>{ props.place.isTouched ? "TOUCHED" : "" } < /div>
< button onClick = { setTouched } > SetTouched < /button>
< /div>
);
};
https://codesandbox.io/s/wonderful-black-m6il1
Upvotes: 1