下面的两种方法都有效,但是使用一种方法对性能有什么影响吗?
有一个正确性含义:第一个是错误的,第二个是正确的。:-)
在你的第一个例子,你调用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>
而 with() => 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:如果您传递的新状态不是基于当前状态或props,则无需使用函数形式。在您的示例中,它不是,因此您的示例是可以使用非回调表单的地方之一:
this.setState(
{ result: '1-1' },
() => this.clearResult(500)
);
这不,如果你正在使用从什么是好的this.state
或this.props
。在这种情况下,使用回调的形式和它的prevState
和props
参数。总是。总是使用回调形式没有什么坏处,函数调用的开销在现代 JavaScript 引擎上非常微不足道。(在本世纪最慢的 JS 引擎上甚至是微不足道的:IE6 中的引擎。)
更多关于这里和这里。