Object.assign({}, object1, object2, {prop: value});
const newObject = {
...object1,
...object2,
prop: value,
}
newObject === object1 // false
newObject[obj1OnlyProp] === object1[obj1OnlyProp] // true !
Shallow copy
const state = {
sets: [{
id: 1,
name: 'First set',
locations: [{
id: 1,
setId: 1,
name: 'First location',
jobs: [{id: 1, locationId: 1, name: 'First job'}, {id: 2, locationId: 1, name: 'Second job'}]
}, {
id: 2,
setId: 1,
name: 'Second location',
jobs: [{id: 3, locationId: 2, name: 'Third job'}, {id: 4, locationId: 2, name: 'Fourth job'}]
}]
}, {
id: 2,
name: 'Second set',
locations: [{
id: 3,
setId: 2,
name: 'Third location',
jobs: [{id: 5, locationId: 3, name: 'Fifth job'}, {id: 6, locationId: 3, name: 'Sixth job'}]
}, {
id: 4,
setId: 2,
name: 'Fourth location',
jobs: [{id: 7, locationId: 4, name: 'Seventh job'}, {id: 8, locationId: 4, name: 'Eighth job'}]
}]
}]
};SET
LOCATION
JOB
JOB DATE
SHIFT
const normalizedState = {
sets: {
1: {
id: 1,
name: 'First set',
locations: [1, 2]
},
2: {
id: 2,
name: 'Second set',
locations: [3, 4]
}
},
locations: {
1: {
id: 1,
setId: 1,
name: 'First location',
jobs: [1, 2]
},
2: {
id: 2,
setId: 1,
name: 'Second location',
jobs: [3, 4]
},
....
},
jobs: {
1: {
id: 1,
locationId: 1,
name: 'First job'
},
2: {
id: 2,
locationId: 1,
name: 'Second job'
},
...
}
};Change detection
function updateSet(state, payload) {
return {
...state,
sets: {
...state.sets,
[payload.id]: {
...state.sets[payload.id],
...payload
}
}
}
}function updateSet(state, payload) {
return {
...state,
sets: {
...state.sets,
[payload.id]: {
...state.sets[payload.id],
...payload
}
}
}
}
function updateLocation(state, payload) {
...
return updateSet(updatedState, set);
}
function updateJob(state, payload) {
const job = state.jobs[payload.id];
const location = state.locations[job.locationId];
return updateLocation({
...state,
jobs: {
...state.jobs,
[payload.id]: {
...job,
...payload
}
}
}, location);
}function updateJobs(state, payload: any[]) {
let tempState= state;
payload.forEach(jobPayload => {
const job = state.jobs[jobPayload.id];
const location = state.locations[job.locationId];
tempState = updateLocations({
...state,
jobs: {
...state.jobs,
[jobPayload.id]: {
...job,
...jobPayload
}
}
}, [location]);
});
return tempState;
}function updateJobs(state, payload: any[]) {
const jobs = {};
const locations = {};
payload.forEach(jobPayload => {
const job = state.jobs[jobPayload.id];
locations[job.locationId] = locations[job.locationId] || state.locations[job.locationId];
jobs[jobPayload.id] = {
...job,
...jobPayload
}
});
return updateLocations({
...state,
jobs: {
...state.jobs,
...jobs
}
}, Object.keys(locations).map(id => locations[id]));
}function updateJobs(state, payload: any[]) {
const jobs = {};
const locations = {};
payload.forEach(jobPayload => {
const job = state.jobs[jobPayload.id];
locations[job.locationId] = locations[job.locationId] || state.locations[job.locationId];
jobs[jobPayload.id] = {
...job,
...jobPayload
}
});
return updateLocations({
...state,
jobs: {
...state.jobs,
byId: {
...state.jobs.byId,
...jobs
}
}
}, Object.keys(locations).map(id => locations[id]));
}function splitReducers(state: CalendarData, action): CalendarData {
return combineReducers({
jobs
});
}
function jobs(state: {allIds: number[], byId: {[id: number]: CalendarJob}}, action) {
return combineReducers({
byId: jobsById,
allIds: jobsAllIds
});
}
function jobsById(state: {[id: number]: CalendarJob}, action): {[id: number]: CalendarJob} {
switch (action.type) {
case UPDATE_JOBS:
return updateJobs(state, action);
default:
return state;
}
}
function updateJobs(state: {[id: number]: CalendarJob}, action): {[id: number]: CalendarJob} {
const jobs = {};
payload.forEach(jobPayload => {
jobs[jobPayload.id] = {
...state.jobs[jobPayload.id],
...jobPayload
}
});
return {
...state,
...jobs
}
}Good luck!