我正在使用React的setState方法,并在状态更新后调用另一个函数。
setState
是否有关于如何调用setState作为回调传递给该函数的首选方法。
以下两种方法都可以使用,但是将一种方法与另一种方法使用会对性能产生影响吗?
this.setState(prevState => { return { result: '1-0' } }, this.clearResult(500))
要么
this.setState(prevState => { return { result: '1-1', } }, () => this.clearResult(500))
我的clearPin方法如下所示。所有这些代码都在React组件内。
clearPin
clearResult(time) { setTimeout(() => { this.setState({ result: '0-0' }) }, time) }
有一个 正确的 含义:第一个是不正确的,第二个是正确的。:-)
在你的第一个例子,你调用this.clearResult(500)和 再 调用setState(与调用的结果this.clearResult(500) - undefined,在你的榜样- 作为它的第二个参数)。this.setState(prevState => { ... }, this.clearResult(500));就像foo(bar()) —首先调用bar,然后将调用结果传递到中foo。
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,并且在状态更改回调被调用 之前的 调用:
clearResult
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(和之后的状态变化):
() => this.clearResult(500)
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) );
如果您使用或中的内容,那 将是不可能的 。在这种情况下,请使用回调形式及其和参数。总是。而且始终使用回调形式没有什么害处,在现代JavaScript引擎上,函数调用的开销异常小。(在本世纪最慢的JS引擎上,它甚至是微不足道的:IE6中的那个。)this.state``this.props``prevState``props
this.state``this.props``prevState``props
在这里和这里更多。