使用变量在reducer中更新状态

4

我正在构建一个简单的应用程序,根据其状态展开和折叠内容区域。基本上,如果collapse = false,则添加一个类,如果为true,则添加不同的类。

我正在使用Next.js和Redux,并遇到了一个问题。我想根据操作传递的参数更新状态。它没有更新状态,我不确定为什么或更好的替代方案是什么。任何澄清都将非常好!

// DEFAULT STATE    
const defaultState = {
  membership: 'none',
  sectionMembership: {
    id: 1,
    currentName: 'Membership',
    nextName: 'General',
    collapse: false
  },
  sectionGeneral: {
    id: 2,
    prevName: 'Membership',
    currentName: 'General',
    nextName: 'Royalties',
    collapse: true
  }
}

// ACTION TYPES
export const actionTypes = {
  SET_MEMBERSHIP: 'SET_MEMBERSHIP',
  MOVE_FORWARDS: 'MOVE_FORWARDS',
  MOVE_BACKWARDS: 'MOVE_BACKWARDS'
}

// ACTION
export const moveForwards = (currentSection) => dispatch => {
  return dispatch({ type: actionTypes.MOVE_FORWARDS, currentSection })
}

// REDUCERS
export const reducer = (state = defaultState, action) => {
  switch (action.type) {
      case actionTypes.SET_MEMBERSHIP:
        return Object.assign({}, state, {
          membership: action.membershipType
        })
      case actionTypes.MOVE_FORWARDS:
        const currentId = action.currentSection.id
        const currentName = "section" + action.currentSection.currentName    
        return Object.assign({}, state, {
          currentName: {
            id: currentId,
            collapse: true
          }
        })
    default: return state
  }
}

当前的 currentName 变量导致状态无法更新。我希望能够动态更改每个部分的状态,这就是为什么我认为可以使用变量并像这样更新状态。

似乎不能在键/值对中使用变量作为键。为什么?有没有其他动态更新状态的替代方法?


在你的 Object.assign 中,使用方括号将 currentName 包围起来。像这样:[currentName]。请参阅 Object initializer 中的 Computed property names - Sam R.
2个回答

3

这是因为JavaScript理解为你想创建一个名为currentName的键,而不是一个带有变量currentName值的键。为了实现你想要的效果,你需要将currentName用括号括起来:

return Object.assign({}, state, {
          [currentName]: {
            id: currentId,
            collapse: true
          }
        })

因此,它将理解关键字将是currentName


这很有道理,谢谢!是否可以传递状态中未更改的其余属性?(例如nextName,currentName)我的组件正在接收更新状态,但仅限于更改的内容而不是整个对象。 - onehunnid
是的,如果您使用ES6,只需执行[currentName]: { id: currentId, collapse: true, ...this.state[currentName] }即可。有关更多信息,请参见Wes Bos的文章 - Tiago Alves
希望能有所帮助! - Tiago Alves

0

这也是正确的:

return Object.assign({}, state, {
  [currentName]: Object.assign({}, state[currentName], {
    id: currentId,
    collapse: true
  })
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接