我正在从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。
答案 0 :(得分:2)
mapStateToProps 将您的redux存储区连接到组件的props。道具更新时,组件不会重新渲染(除非道具属于父状态的状态)。 当您的组件状态更新时,会调用 componentDidUpdate 。更换道具不会对此产生影响。 简而言之,redux商店中的道具不会遵循组件的生命周期挂钩。 您可能需要从调用redux状态的调度的地方触发重新渲染组件。
答案 1 :(得分:2)
mapStateToProps
之后调用 dispatch
。
然后Redux会检查返回的结果是否与上一个参考结果不同。仅当存在差异时,组件才提供新的道具。运行componentDidUpdate
和render
。
因此,您要么返回的参考数据都是相同的数据,另一方面是错过更新组件的合法理由(并节省了一些时间以获得更好的性能)。
或者你的化简器正在改变状态(对于Redux来说是不行的),你应该解决这个问题。