React componentDidUpdate没有收到最新的道具

时间:2017-07-09 00:41:16

标签: reactjs redux

在Redux中,我在redux-thunk动作创建器中运行以下命令:

dispatch({type: "CASCADING_PROMPT_STATUS", promptName, list: 'model', status: 'disabled'});
dispatch({type: "CASCADING_PROMPT_STATUS", promptName, list: 'model', status: 'enabled'});

这会触发reducer两次,我可以在控制台中看到Redux状态从禁用状态更改 - >启用。

在React中,我有以下组件,其中道具连接到CASCADING_PROMPT_STATUS更新的状态。

但是,在我的组件中,我正在检查状态是否已在componentDidUpdate(prevProps)中更改

这不会触发。

如果我将动作创建者更改为延迟第二个调度setTimeout(<dispatch...>, 1);甚至一毫秒,则prevProps!== this.props,这就是我所期望的。

我的组件连接到redux,如下所示:

const C_Component = connect(mapStateToProps, mapDispatchToProps, null, {pure: false})(Component);

React批量改变道具吗?为什么我要延迟第二次发货?我认为redux dispatch是同步的。

编辑:我更新redux状态的方式如下:

var newState = {};

if (!_.isUndefined(state)){
    newState = _.cloneDeep(state);
}
...
    case "CASCADING_PROMPT_STATUS":
        newState[action.promptName][action.list].disable = action.status === 'disabled';
        break;

1 个答案:

答案 0 :(得分:1)

Redux调度是同步的(除非中间件拦截并延迟操作)。但是,在大多数情况下,React更新都是批处理的。

其次,您的reducer肯定会改变状态,因为您不会复制每个级别的嵌套需要更新。突变将导致您的连接组件认为没有任何更改,并跳过更新。有关如何正确执行不可更新的更多详细信息,请参阅文档的Structuring Reducers - Immutable Update Patterns部分。

实际上......重新阅读你的减速器,你 做了一个深层次的克隆,所以理论上它并没有变异。但是,根据Redux常见问题解答,deep cloning is a bad idea。相反,您应该执行嵌套浅层更新

第三,您的shouldComponentUpdate不应该自己比较this.propsnextProps。实际的道具对象本身肯定会有所不同。相反,它应该比较那些对象的内容 - 即props.a !== nextProps.a && props.b !== nextProps.b等。这被称为“浅层相等比较”。