mapStateToProps,但未调用componentDidUpdate

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mapStateToProps,但未调用componentDidUpdate相关的知识,希望对你有一定的参考价值。

我正在从api获取GameChart的数据并更改redux状态。在GameChart.jsx文件中,当componentDidUpdate调用时,我绘制了图表。但是,redux状态更改有时不调用componentDidUpdate。


*控制台日志*

[GameChart.jsx控制台日志,未调用componentDidUpdate时(发生魔术的机会为50/50 ...):

Chart mapStateToProps 
Chart componentDidMount
Chart mapStateToProps 

[GameChart.jsx控制台日志,当一切正常时,并且在redux状态更改时调用componentDidUpdate:

Chart mapStateToProps 
Chart componentDidMount
Chart mapStateToProps 
Chart mapStateToProps 
Chart componentDidUpdate 
Chart mapStateToProps 


这里是非常示意性的代码:

GameChart.jsx

import React, { Component } from 'react';
import { connect } from 'react-redux';

class GameChart extends Component {
    ...

    componentDidMount() { console.log("Chart componentDidMount") }

    componentDidUpdate() {
        console.log("Chart componentDidUpdate");

        /* When socket.js call initGame, and redux update state, I need to 
           render canvas from this state inside GameChart.jsx */

        ... Drawing chart, using data from this.props.game ...
    }

    render() {
        return (
           <canvas ref={...} ... />
        );
    }
}

const mapStateToProps = state => {
    console.log('Chart mapStateToProps');

    return { game: state.game }
};

export default connect(mapStateToProps)(GameChart);

gameReducer.js。动作,initGame称为

case INIT_GAME:
    return {
        status: action.payload.roll !== null ? "rolling" : "betting",
        ...action.payload
    }

socket.js

/* When websocket connected, it sends current game state to client.
Client need to write this state in redux state and re-render
GameChart.jsx, using this new rewrited by dispatch action state */

socket.onmessage = (msg) => {
    store.dispatch(initGame)(msg);
}


我检查了redux-dev-tools。显示“差异”选项卡,该游戏成功启动并且状态更改为websocket提供的内容。我检查了redux状态突变,没有状态突变。刷新页面时,有时魔术般未调用componentDidUpdate,但有时调用了。它可以任意调用,机会为50/50。

答案

mapStateToProps将您的redux存储连接到组件的prop。当您的道具更新时,组件不会重新渲染(除非这些道具属于父级状态)。componentDidUpdate在组件状态更新时被调用。更换道具不会对此产生影响。简而言之,redux商店中的道具不会遵循组件的生命周期挂钩。您可能需要从调用redux状态的调度的地方触发组件的重新渲染。

另一答案

mapStateToProps在运行dispatch之后被调用。然后Redux会检查返回的结果是否与上一个参考结果不同。仅当存在差异时才提供新的道具。运行componentDidUpdaterender

因此,您要么返回了参照相同的数据,而且是错过更新组件的合法理由(并节省了一些时间以获得更好的性能)。

或者您的reducer正在改变状态(对于Redux来说,这是不行的,您应该解决该问题。

以上是关于mapStateToProps,但未调用componentDidUpdate的主要内容,如果未能解决你的问题,请参考以下文章

如何为调用 reduxjs 的 mapStateToProps 的反应组件编写单元测试?

javascript 它应该调用mapStatetoProps

调度操作时未调用redux connect mapStateToProps

我应该使用 useselector/useDispatch 而不是 mapStateToProps

反应 redux 异步 mapStateToProps

我可以在 Redux 中没有 mapStateToProps 的 mapDispatchToProps 吗?