反应设置状态回调传递参数的正确方法 [英] react set state callback correct way to pass an argument
问题描述
我正在使用React的setState
方法,并在状态更新后调用另一个函数.
I am using React's setState
method, and calling another function when the state has been updated.
对于如何调用作为回调传递给setState
的函数,是否存在首选方法.
Is there a preferred approach as to how to call the function that is passed to setState
as a callback.
以下两种方法都可以使用,但是将一种方法用于另一种方法是否会对性能产生影响?
Both of the approaches below work but is there any performance implications of using one over the other?
this.setState(prevState => {
return {
result: '1-0'
}
}, this.clearResult(500))
或
this.setState(prevState => {
return {
result: '1-1',
}
}, () => this.clearResult(500))
我的clearPin
方法如下所示.所有这些代码都在React组件中.
My clearPin
method looks like the following. All of this code is within a React component.
clearResult(time) {
setTimeout(() => {
this.setState({
result: '0-0'
})
}, time)
}
推荐答案
以下两种方法都可以使用,但是将一种方法用于另一种方法是否会对性能产生影响?
Both of the approaches below work but is there any performance implications of using one over the other?
有一个正确性含义:第一个是不正确的,第二个是正确的. :-)
There's a correctness implication: The first one is incorrect, the second one is correct. :-)
在第一个示例中,您先调用this.clearResult(500)
,然后然后调用setState
(在本示例中,调用this.clearResult(500)
–— undefined
;作为第二个参数). this.setState(prevState => { ... }, this.clearResult(500));
就像foo(bar())
首先调用bar
,然后将调用结果传递到foo
.
In your first example, you're calling this.clearResult(500)
and then calling setState
(with the result of calling this.clearResult(500)
— undefined
, in your example — as its second argument). this.setState(prevState => { ... }, this.clearResult(500));
is just like foo(bar())
— first it calls bar
, then it passes the result of calling it into foo
.
在第二个示例中,您正在将一个函数传递给setState
,当状态更新时它将调用该函数.
In your second example, you're passing a function into setState
that it will call when the state is updated.
您想要第二种形式(或其他多种形式之一).
You want the second form (or one of the various equivalents to it).
this.setState(prevState => {
return {
result: '1-1',
}
}, () => this.clearResult(500));
// or: }, this.clearResult.bind(this, 500));
// But the arrow is clear and idiomatic
这里证明您的第一个示例在调用setState
之前和在调用setState
之前以及在状态更改回调之前调用clearResult
:
Here's proof that your first example is calling clearResult
before calling setState
, and before your state change callback is called:
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)
代替,在setState
之后(以及状态更改之后)调用clearResult
:
whereas with () => this.clearResult(500)
instead, clearResult
is called after setState
(and after the state change):
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:如果需要,您可以更简洁一些:
Side note 1: If you want, you can be a bit more concise:
this.setState(
() => ({ result: '1-1' }),
() => this.clearResult(500)
);
注释2:如果您要传递的新状态不是(基于当前状态或道具),则无需使用函数表单.在您的示例中,事实并非如此,因此您可以使用无回调形式:
Side note 2: There's no need to use the function form if the new state you're passing isn't based on current state or props. In your example, it isn't, so yours is one of the places where using the non-callback form is okay:
this.setState(
{ result: '1-1' },
() => this.clearResult(500)
);
如果您使用的是this.state
或this.props
中的内容,不会没问题.在这种情况下,请使用回调形式及其prevState
和props
参数.总是.始终使用回调形式几乎没有什么害处,在现代JavaScript引擎上,函数调用的开销微不足道. (在本世纪最慢的JS引擎上,它甚至是微不足道的:IE6中的那个.)
That would not be okay if you were using something from this.state
or this.props
. In that situation, use the callback form and its prevState
and props
parameters. Always. And there's little harm in always using the callback form, the overhead of a function call is exceptionally trivial on modern JavaScript engines. (It was even trivial on the slowest JS engine of this century: The one in IE6.)
这篇关于反应设置状态回调传递参数的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!