我是新来的反应者,完全坚持这一点。
说我有一个具有以下结构的简单应用程序:
<App>
|___<Container>
|___<Chart>
在<App>
的某个地方,我有一个事件,该事件会修改<Container>
的道具,然后根据这些道具将<Container>
中的查询方法触发到数据库,这需要一定的时间。时间量(例如1秒)。查询返回后,它将修改<Container>
的状态,特别是进入<Chart>
属性的数据属性。
现在说,我希望<Chart>
能够看到<App>
的旧道具和新道具之间发生了什么变化(假设这些道具也一直传递到<Chart>
)。我们得到的是:
应用事件->修改应用状态->根据道具更新容器->触发查询
但是我可以在哪里放置“火灾查询”功能?如果我在ComponentDidUpdate中这样做,则意味着我丢失了先前的道具,因为查询修改了<Container>
的状态,从而第二次更新了<Chart>
,这意味着第二次更新了'prevProps' <App>
元素中的事件之后,道具将已经更新。
我在这里可以做什么?我在这里看不到如何使用shouldComponentUpdate,因为那会在更新之前触发,并且我需要触发'update'事件,以便<Container>
元素有理由在事件发生后重新获取数据。 <App>
。
任何帮助将不胜感激!
答案 0 :(得分:0)
在道具与状态之间似乎有些混乱。将状态视为该组件的私有状态。容器的更新状态并不意味着道具已更改。
想想电灯开关。状态为开或关。但是,家庭设计师可能已经定义了某些属性,并将它们围绕颜色和形状等内容传递给室内设计团队。这些是分开的。
关键是电灯开关可以处于打开或关闭状态,这不会改变电灯开关的属性。
在您的示例中,道具历史可以作为容器状态的一部分进行跟踪。
class Container extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [
[Math.random(), Math.random(), Math.random()]
]
}
}
componentDidMount() {
setInterval(() => this.setState({
data: [
...this.state.data,
[Math.random(), Math.random(), Math.random()]
]
}), 5000)
}
render() {
return (
<Chart data={this.state.data} />
);
}
}
class Chart extends React.Component {
render() {
const data = this.props.data.slice(-2);
const previousDataSum = (data[0] || []).reduce((total, current) => total + current, 0);
const currentDataSum = (data[1] || []).reduce((total, current) => total + current, 0);
return (
<div>
<div>
PrevPropsSum: {previousDataSum}
</div>
<div>
CurrentPropsSum: {currentDataSum}
</div>
<div>
Difference: {previousDataSum && currentDataSum ? previousDataSum - currentDataSum : 0}
</div>
</div>
)
}
}
ReactDOM.render(<Container />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>