以下两种方法都有效,但使用其中一种方法是否会对性能产生影响?
有一个正确性的含义:第一个是不正确的,第二个是正确的。 :-)
在您的第一个示例中,您调用 this.clearResult(500) 并且 然后 调用 setState(调用 this.clearResult(500) - undefined 的结果,在您的示例中 - 作为它的第二个参数)。 this.setState(prevState => { ... }, this.clearResult(500)); 就像 foo(bar()) - 首先它调用 bar,然后将调用它的结果传递给 foo。
在您的第二个示例中,您将一个函数传递给setState,当状态更新时它将调用该函数。
你想要第二种形式(或它的各种等价形式之一)。
this.setState(prevState => {
return {
result: '1-1',
}
}, () => this.clearResult(500));
// or: }, this.clearResult.bind(this, 500));
// But the arrow is clear and idiomatic
这里证明您的第一个示例是在调用clearResult 之前调用setState,并且在调用您的状态更改回调之前:
class Example extends React.Component {
constructor(...args) {
super(...args);
this.state = {value: "a"};
}
// Overriding it PURELY to show what's happening
setState(...args) {
console.log("setState called");
return super.setState(...args);
}
componentDidMount() {
this.setState(
() => {
console.log("state change callback");
return {value: "b"};
},
this.clearResult(500)
);
}
clearResult(delay) {
console.log("clearResult called");
setTimeout(() => {
this.setState({value: "c"});
}, delay);
}
render() {
return <div>{this.state.value}</div>;
}
}
ReactDOM.render(
<Example />,
document.getElementById("root")
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
而用() => this.clearResult(500) 代替,clearResult 在setState 之后调用(并且在状态更改之后):
class Example extends React.Component {
constructor(...args) {
super(...args);
this.state = {value: "a"};
}
// Overriding it PURELY to show what's happening
setState(...args) {
console.log("setState called");
return super.setState(...args);
}
componentDidMount() {
this.setState(
() => {
console.log("state change callback");
return {value: "b"};
},
() => this.clearResult(500)
);
}
clearResult(delay) {
console.log("clearResult called");
setTimeout(() => {
this.setState({value: "c"});
}, delay);
}
render() {
return <div>{this.state.value}</div>;
}
}
ReactDOM.render(
<Example />,
document.getElementById("root")
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
旁注1:如果你愿意,你可以更简洁一点:
this.setState(
() => ({ result: '1-1' }),
() => this.clearResult(500)
);
旁注2:如果您传递的新状态不是基于当前状态或道具,则无需使用函数形式。在您的示例中,情况并非如此,因此您的示例是可以使用非回调表单的地方之一:
this.setState(
{ result: '1-1' },
() => this.clearResult(500)
);
如果您使用来自this.state 或this.props 的东西,那不会没问题。在这种情况下,使用回调表单及其prevState 和props 参数。总是。而且总是使用回调形式并没有什么坏处,函数调用的开销在现代 JavaScript 引擎上是非常微不足道的。 (在本世纪最慢的 JS 引擎上什至微不足道:IE6 中的那个。)
更多关于here 和here。