反应设置状态回调传递参数的正确方法 [英] react set state callback correct way to pass an argument

查看:84
本文介绍了反应设置状态回调传递参数的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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.statethis.props中的内容,不会没问题.在这种情况下,请使用回调形式及其prevStateprops参数.总是.始终使用回调形式几乎没有什么害处,在现代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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆