在下面的示例中,我使用 ES6 Map 作为 React 中的状态值:
class App extends React.Component {
constructor(props) {
super(props);
const results = new Map();
results["group1"] = [{ value: "..." }, { value: "..." }];
this.state = { results };
}
onUpdateClick(i) {
this.state.results["group1"][i].value = i;
this.setState({});
}
onResetClick(i) {
this.state.results["group1"][i].value = "...";
this.setState({});
}
render() {
const { results } = this.state;
return (
<div>
{results["group1"].map((r, i) => (
<div>
{r.value}
<button onClick={e => this.onUpdateClick(i)}>update</button>
<button onClick={e => this.onResetClick(i)}>reset</button>
</div>
))}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("container"));
<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='container'></div>
当您单击按钮时,我会直接更新 map ,然后调用不带参数的 setState。我不制作 map 的克隆/深拷贝。根据我对 React 文档的理解,这应该不起作用,并且在文档中明确警告:
Never mutate this.state directly as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable
( https://reactjs.org/docs/react-component.html#state )
文档还指出比较是浅表的,因此使用空对象调用肯定不会导致合并,因此不会重新渲染?
为什么这个例子有效?
(我还应该注意,我也用 React v16.9.0 重现了这种行为)
编辑: 我还想指出(因为很多答案都提到我正在传递一个空对象这一事实)如果我这样调用 setState,组件将被重新渲染(和更新):
this.setState({ results: this.state.results })
这似乎不应该导致重新渲染
最佳答案
来自文档:setState
setState() will always lead to a re-render unless shouldComponentUpdate() returns false.
这意味着无论您是否将更改作为参数传递,this.setState({});
都会导致重新渲染
关于javascript - 为什么 React 在直接改变状态时会更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62472159/