React Redux元素不更新

时间:2017-03-28 10:04:53

标签: javascript reactjs redux

我有一个Table组件,它为项列表呈现行:

return <Row style={styles.row} key={idx} item={item} onSelect={this.props.onRowSelect}>
    {columns.map((col, idx) => {
        return <Column style={col.style} key={`${item._id}_${col.key}`}
                       width={col.width || this._defaultCellWidth} type={col.type}>
            {_.get(item, col.key)}
        </Column>
    })}
    </Row>

每个项目都有selected:bool值,该值绑定到每行的复选框。

另外,我有一个HeaderRow,它有select all的复选框。 通过选中复选框,我将调度一个事件来更新所选字段。 国家本身已更新,但没有退回。 我的行动是:

if(action.id) 
{
    let index = state.items.findIndex(item => item._id == action.id);
    state.items[index].selected = action.selected;
}
else
{
    state.items.map(e=>e.selected = action.selected);
}

return 
{
    ...state,
    items: state.items
}

编辑: 这是一个很好的解决方案:

if(action.id) {
            let index = state.items.findIndex(item => item._id == action.id);
            state.items[index].selected = action.selected;
            return {
                ...state
            }

        }else{
            return {
                ...state,
                items: state.items.map((item, index) => {
                    return Object.assign({}, item, {
                        selected: action.selected
                    })
                })
            }
        }

2 个答案:

答案 0 :(得分:2)

请记住all data in the Redux store must be considered immutable"[a reducer] must never mutate its arguments")。

您正在改变state.items中的项目,并且由于items仍然是同一个对象,因此Redux认为它保持不变,因此视图不会更新。

答案 1 :(得分:0)

经常发生的常见错误。请查看this article,因为它解释了如何安全地更新各种级别。

在你的情况下它应该是这样的:

return 
{
    // Copy the current state
    ...state,
    // Replace the items array with a new version,
    // by creating a new array through the map() call.
    items: state.items.map((item, index) => {
        // This isn't the item in the array we are looking
        // for. So simply return it as is.
        if(index != action.id) {
            return item;
        }

        // This is the item to be changed. So copy it and
        // overwrite the selected property.
        return {
            ...item,
            selected: action.selected
        };
    });
}