在下面的示例中,我使用 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。我不制作地图的克隆/深层副本。根据我对 React 文档的理解,这应该不起作用,并且在文档中明确警告:
永远不要直接改变 this.state ,因为之后调用 setState() 可能会替换你所做的改变。将 this.state 视为不可变
(https://reactjs.org/docs/react-component.html#state)
文档还指出比较很浅,所以用空对象调用肯定会导致没有合并,因此不会重新渲染?
为什么这个例子有效?
(我还应该注意,我也使用 React v16.9.0 重现了这种行为)
编辑:我还想指出(因为许多答案是指我传递一个空对象的事实)如果我像这样调用 setState 组件将被重新渲染(和更新):
this.setState({ results: this.state.results })
这似乎不应该导致重新渲染