React componentDidUpdate 没有收到最新的props

IT技术 reactjs redux
2021-05-04 08:16:36

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

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

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

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

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

这不会触发。

如果我更改动作创建者以将第二次分派延迟setTimeout(<dispatch...>, 1);甚至一毫秒,prevProps !== this.props,这正是我所期望的。

我的组件像这样连接到 redux:

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

React 会批量调整props吗?为什么我必须延迟第二次派遣?我认为 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个回答

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

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

实际上......重新阅读你的reducer,你正在做一个深度克隆,所以理论上这不会发生变异。但是,根据 Redux 常见问题解答,深度克隆是一个坏主意相反,您应该进行嵌套的浅更新

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