I am working on a Nextjs application with Typescript and would like to update a nested object state. Here is how the state looks like:
const initialState ={
userInfo: string | null
isLoading: boolean,
cursorState: boolean,
companyProfile:{
companyDescription?: string
companyLogo?: string
companyLogoPublicId?: string
companyName?: string
owner?: string
_id?: string
}
}
This is the reducer function:
const Reducer = (state: initialStateAttributes, action: actionAttributes) =>{
switch(action.type){
case actionEnum.COMPANY_PROFILE_DATA:
return{
...state,
companyProfile: {...state.companyProfile,
companyDescription: action.payload,
companyLogo: action.payload,
companyLogoPublicId: action.payload,
companyName: action.payload,
owner: action.payload,
_id: action.payload
}
}
}
}
And I am dispatching the action to update the state via API response data like this:
const res = await axiosPrivate.get<axiosGetCompanyProfile>(`/getcompany`, {withCredentials:
true, headers: {Authorization: `${data?.user.token}`}});
dispatch({type: actionEnum.COMPANY_PROFILE_DATA, payload: res?.data });
I would like to update the entire state of companyProfile values on each update. I am not targeting one value at a time. I would like to change all values per update. The current way that I tried simply created each companyProfile value with all the payload on each of them.
How do I approach this?
>Solution :
I would like to update the entire state of companyProfile values on
each update. I am not targeting one value at a time. I would like to
change all values per update.
If I’m understanding this correctly it sounds like you would like to update the entire state.companyProfile value with the action payload value. Any state, and nested state, that is being updated should be shallow copied, and then overwrite the properties you want to update.
const { data } = await axiosPrivate.get<axiosGetCompanyProfile>(
"/getcompany",
{
withCredentials: true,
headers: {
Authorization: `${data?.user.token}`
},
},
);
dispatch({
type: actionEnum.COMPANY_PROFILE_DATA,
payload: data // <-- action payload is companyProfile data
});
const reducer = (
state: initialStateAttributes,
action: actionAttributes
) => {
switch(action.type) {
case actionEnum.COMPANY_PROFILE_DATA:
return {
...state, // <-- previous state shallow copied
companyProfile: action.payload, // <-- set value
};
...
default:
return state;
}
};
If you want to "merge" new companyProfile data with existing state.companyProfile state then continue the "shallow copy, then overwrite" pattern.
const reducer = (
state: initialStateAttributes,
action: actionAttributes
) => {
switch(action.type) {
case actionEnum.COMPANY_PROFILE_DATA:
return {
...state,
companyProfile: {
...state.companyProfile, // <-- preserve existing
...action.payload, // <-- overwrite with new
},
};
...
default:
return state;
}
};