next.js 如何使用useReducer更新嵌套对象状态?

3vpjnl9f  于 2023-06-22  发布在  其他
关注(0)|答案(1)|浏览(118)

我正在使用Typescript开发一个Nextjs应用程序,希望更新一个嵌套的对象状态。下面是状态的样子:

const initialState ={
  userInfo: string | null
  isLoading: boolean,
  cursorState: boolean,
  companyProfile:{
    companyDescription?: string
    companyLogo?: string
    companyLogoPublicId?: string
    companyName?: string
    owner?: string
    _id?: string
  }
}

这是reducer函数:

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
        }
      }
  }
}

我通过API响应数据调度动作来更新状态,如下所示:

const res = await axiosPrivate.get<axiosGetCompanyProfile>(
  `/getcompany`,
  {
    withCredentials: true,
    headers: {
      Authorization: `${data?.user.token}`
    }
  }
);
dispatch({
  type: actionEnum.COMPANY_PROFILE_DATA,
  payload: res?.data
});

我想在每次更新时更新companyProfile值的整个状态。我不是一次只针对一个值。我想在每次更新时更改所有值。我尝试的当前方法只是创建每个companyProfile值,每个值上都有所有有效负载。
我该如何处理这个问题?

fnx2tebb

fnx2tebb1#

我想在每次更新时更新companyProfile值的整个状态。我不是一次只针对一个值。我想在每次更新时更改所有值。
如果我的理解正确的话,听起来你想用action payload值更新整个state.companyProfile值。应该浅复制正在更新的任何状态和嵌套状态,然后覆盖要更新的属性。

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;
  }
};

如果要将新的companyProfile数据与现有的state.companyProfile状态“合并”,则继续“浅拷贝,然后覆盖”模式。

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;
  }
};

相关问题