我正在使用React的setState
方法,并在状态更新后调用另一个函数。
是否有一种首选方法可以调用作为回调传递给setState
的函数。
以下两种方法都有效,但使用其中一种方法会产生什么性能影响?
this.setState(prevState => {
return {
result: '1-0'
}
}, this.clearResult(500))
或
this.setState(prevState => {
return {
result: '1-1',
}
}, () => this.clearResult(500))
我的clearPin
方法如下所示。所有这些代码都在React组件中。
clearResult(time) {
setTimeout(() => {
this.setState({
result: '0-0'
})
}, time)
}
答案 0 :(得分:8)
以下两种方法都有效,但使用其中一种方法会产生什么性能影响?
有一个正确性暗示:第一个是不正确的,第二个是正确的。 : - )
在您的第一个示例中,您呼叫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中的那个。)