Redux嵌套对象作为状态 - 这是可能的/最佳的



我是 Redux 的新手,所以请耐心等待。我想知道以下情况是否可能和/或最佳,如果是这样,您如何更新化简器中的嵌套对象值?

const initialState = {
  banner: {
    backgroundColor: 'black',
    text: 'Some Title',
    textColor: 'white',
    image: null
  },
  nav: {
    mainOpen: false,
    authOpen: false,
  }
  ...
}

然后在减速器中,这样的东西似乎不起作用......

export default function reducer(state = initialState, action = {}) {
  const {type, data} = action;
  switch (type) {
    case SET_BANNER_TEXT:
      return {
        ...state,
        banner.text: data //<-- ****THIS FAILS WITH UNEXPECTED TOKEN!!!****
      }
    ...
}
还是有一个"横幅"减速器

、一个"导航"减速器等

更好??

啪!

我对 redux 也有点陌生,所以我不能过多地谈论"最佳实践"。 我个人倾向于一个新的化简器,因为你有特定的操作,如SET_BANNER_TEXT(颜色,img等?)来修改状态树的特定部分,而不是其他。 通过将减速器分开(即使有很多减速器)使它们变得简单,将使事情更容易追踪。

从语法上讲,您可以使用以下内容实现您尝试做的事情:

export default function reducer(state = initialState, action = {}) {
  const {type, data} = action;
  switch (type) {
    case SET_BANNER_TEXT:
      const newBannerState = Object.assign({}, state.banner, {text: data});
      return Object.assign({}, state, {banner: newBannerState});
}

由于您要更新对象的键,请尝试使用它来更新键

const state = {
  ...initialState,
  banner: {
    ...initialState.banner, // extend
    text: 'newText'
  }
}

翻译为

var state = _extends({}, initialState, {
    banner: _extends({}, initialState.banner, {
        text: 'newText'
    })
});

在 ES5 中

检查此JSBINb

编辑:如下面的注释中所述,如果使用上面的代码,它将覆盖整个横幅对象。您可以使用Object.assign()尝试此线程中的其他答案并克隆banner对象。如果您仍然想使用点差运算符,我更新了我的答案。

我认为最好为深度嵌套状态使用特定的化简器。我会写成这样

export function rootReducer(state = initialState, action) {
    switch (action.type) {
    case SET_BANNER_TEXT:
    case SET_BANNER_BG:
        return Object.assign({}, state,
            {
                banner: bannerReducer(state.banner, action)
            }
        );
    // ...
    default:
        return state;
    }
}
function bannerReducer(state, action) {
    switch (action.type) {
    case SET_BANNER_TEXT:
        return Object.assign({}, state, {text: action.payload});
    case SET_BANNER_BG:
        return Object.assign({}, state, {backgroundColor: action.payload});
    // ...
    default:
        return state;
    }
}

最新更新