我有一个完整的运行代码,但它有一个缺陷 . 它从render()内部调用setState() . 因此,反应会引发反模式警告 .
Cannot update during an existing state transition (such as within render or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to componentWillMount
我的逻辑是这样的 . 在 index.js 父组件中,我有如下代码 . 构造函数()使用初始值调用图()以显示图形 . 用户还有一个表单来指定新值并提交表单 . 它使用新值再次运行图形()并重新渲染图形 .
import React, { Component } from 'react';
import FormComponent from './FormComponent';
import PieGraph from './PieGraph';
const initialval = '8998998998';
class Dist extends Component {
constructor() {
this.state = {
checkData: true,
theData: ''
};
this.graphs(initialval);
}
componentWillReceiveProps(nextProps) {
if (this.props.cost !== nextProps.cost) {
this.setState({
checkData: true
});
}
}
graphs(val) {
//Calls a redux action creator and goes through the redux process
this.props.init(val);
}
render() {
if (this.props.cost.length && this.state.checkData) {
const tmp = this.props.cost;
//some calculations
....
....
this.setState({
theData: tmp,
checkData: false
});
}
return (
<div>
<FormComponent onGpChange={recData => this.graphs(recData)} />
<PieGraph theData={this.state.theData} />
</div>
);
}
}
FormComponent是一个普通的表单,带有输入字段和提交按钮,如下所示 . 它将回调函数发送到Parent组件,该组件触发graph()和componentWillReceiveProps .
handleFormSubmit = (e) => {
this.props.onGpChange(this.state.value);
e.preventdefaults();
}
代码一切正常 . 有没有更好的方法呢?没有在render()中执行setState?
2 回答
永远不要在渲染中使用setState . 您不应该这样做的原因是因为对于每个setState,您的组件将重新渲染,因此在渲染中执行setState将导致无限循环,这是不推荐的 .
不需要checkData布尔变量 . 您可以直接比较componentWillReceiveProps中的先前成本和当前成本,如果它们不相等,则使用setState将成本分配给Data . 请参阅以下更新的解
还要在所有statefull组件中开始使用shouldComponentUpdate menthod,以避免不必要的重新渲染 . 这是每个statefull组件中最好的实践和推荐方法 .
PS: - 以上解决方案适用于React v15版本 .
您不应该使用 componentWillReceiveProps ,因为在最新版本中,'s UNSAFE and it won'适用于React的异步呈现 .
还有其他方法!
static getDerivedStateFromProps(props, state)
所以在你的情况下
您也可以使用memoization,但在您的情况下,由您决定 . The link has one example where you can achieve the same result with memoization and getDerivedStateFromProps
例如,在改变道具后更新列表(搜索)你可以从这里:
对此: