调用了mapStateToProps,但没有调用componentDidUpdate

时间:2019-12-16 09:59:42

标签: javascript reactjs redux react-redux

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




GameChart.jsx生命周期的控制台日志

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。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

在运行mapStateToProps之后调用

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

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

或者你的化简器正在改变状态(对于Redux来说是不行的),你应该解决这个问题。