【问题标题】:How can I return immutable data from redux reducer?如何从 redux reducer 返回不可变数据?
【发布时间】:2019-08-25 23:05:28
【问题描述】:

对于一个学习和测试项目,我试图从 reducer 返回不可变的 redux 数据,因为组件数据是安全的。这是我的减速器代码:

function itemsReducer(state = [], action) {
    switch(action.type) {
        case 'ITEMS':
            return [...action.data]
        default:
            return state
    }
}

这是我的循环代码:

<ul>
    {
        this.props.items.map((item) => (
            <li>{item.name.first} {item.name.last}</li>
        ))
    }
</ul>

现在一切正常,但在使用此方法更改道具后:

change() {
    this.props.items[0] = 'empty'
}

在再次加载项目后出现此错误:

TypeError: Cannot read property 'first' of undefined

显然,这些项目在我的减速器中没有使用扩展语法复制,所有更改都覆盖了它。在所有索引处执行数据加载操作后 #0 为 'empty'

谢谢

【问题讨论】:

  • Immutable JS怎么样?
  • 你是如何调度动作的,以及在 action.data 中传递了什么?存储中的数据是如何传递给组件的?您的问题可能来自很多地方,请添加更多详细信息
  • @Oliver 我已经映射了 dispatch 并且 action.data 来自我的操作

标签: javascript reactjs redux react-redux immutability


【解决方案1】:

你不应该直接在组件中改变 props,而是在 reducer 中调度一个更新结果的动作

change() {
    this.props.updateItem({first: 'empty'}, 0);
}

动作创建者是

const updateItem = (item, index) => {
   return {type: 'UPDATE_ITEM', item, index}
}

和减速器

function itemsReducer(state = [], action) {
    switch(action.type) {
        case 'ITEMS':
            return [...action.data]
        case 'UPDATE_ITEM': 
            return [...state.slice(0, action.index), {...state[index], ...action.item}, ...state.slice(index+1)];
        default:
            return state
    }
}

【讨论】:

  • 谢谢,但是那个change方法是一种简单的改变props的方法,当然那个方法不适合改变数据。我正在使用该方法测试不可变变量:-)
  • @irbgls 为了避免此类问题,您可以使用 ImmutableJS 以免意外改变道具
  • Khatari 我明白了,但道具不是不可变的?我已经用不可变的语法传递了数据,但是为什么它仍然不是不可变的呢?
  • 使用扩展语法来更新值不会使道具不可变,它只是意味着在处理 ITEMS 动作时,您正在对状态数组进行浅拷贝。还有一个约定,道具不应该被改变,但它们是可变的,就像你在你的情况下注意到的那样。
  • Khatari 是的,它使用扩展语法传递数据,这是我的 api 数据的副本。但是为什么在点击按钮接收数据后我的道具没有刷新并且想要在旧数据上重复?因为那个错误信息...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-22
  • 2017-03-26
  • 1970-01-01
相关资源
最近更新 更多