ホームページ  >  記事  >  ウェブフロントエンド  >  ReactでのsetStateの使い方の詳しい説明

ReactでのsetStateの使い方の詳しい説明

php中世界最好的语言
php中世界最好的语言オリジナル
2018-05-24 14:19:008593ブラウズ

今回は React での setState の使い方について詳しく説明します。 React で setState を使用する際の 注意事項 について、実際のケースを見てみましょう。

質問する

class Example extends Component {
  contructor () {
    super()
    this.state = {
      value: 0,
      index: 0
    }
  }
  componentDidMount () {
    this.setState({value: this.state.value + 1})
    console.log(this.state.value) // 第一次输出
    this.setState({value: this.state.value + 1})
    console.log(this.state.value) // 第二次输出
    setTimeout(() => {
      this.setState({value: this.state.value + 1})
      console.log(this.state.value) // 第三次输出
      this.setState({value: this.state.value + 1})
      console.log(this.state.value) // 第四次输出
    }, 0);
        this.refs.button.addEventListener('click', this.click)
  }
  click = () => {
    this.setState({value: this.state.index + 1})
    this.setState({value: this.state.index + 1})
  }
  render () {
    return (
      <p><span>value: {this.state.value}index: {this.props.index}</span>
        <button>点击</button>
      </p>
    )
  }
}
  • 常識によれば、これら 4 つの出力は 1、2、3、4 です。ただし、実際の出力は 0、0、2、3 です

setState に関する注意事項

  1. setState は React コンポーネントの state の値をすぐには変更しません (つまり、setState は非同期更新です)

  • setState パス キューメカニズムは状態更新を実装します。

  • setState が実行されると、更新する必要がある状態はすぐに更新されるのではなく、マージされて状態キューに入れられます。バッチ;

  • これにより、次に setState が呼び出され、状態キューがマージされると、以前に直接変更された値は無視されます。

setState はコンポーネント Redraw の更新プロセスをトリガーすることによってトリガーされます
    • ここでの再描画とは、React を更新させる 4 つの関数を指します
    • ライフサイクル

      function:

    • shouldComponentUpdate (this.state は更新されません)呼び出されたとき; false が返された場合、ライフサイクルは中断されますが、後続の関数は呼び出されませんが、状態は更新されます)
    • componentWillUpdate (呼び出されたときに this.state は更新されません)
    • render ( this.state は呼び出されると更新されます)
    • componentDidUpdate
    複数の隣接する状態の変更をマージして一度に実行することができます
  •  this.setState({name: 'Pororo'})
     this.setState({age: 20})
    •  this.setState({name: 'Pororo',age: 20})
    と同等です
      効果上記の 2 つのコード ブロックは同じです。各呼び出しがライフサイクル更新をトリガーすると、パフォーマンスは非常に高くなります。したがって、React は複数の this.setState によって生成された変更をキューに入れ、ほぼ同じになった場合にライフサイクルの更新をトリガーします。
    • 問題分析

    • 最初の 2 つの setStates について:

      this.setState({value: this.state.val + 1});
      console.log(this.state.value); // 第一次输出
      this.setState({value: this.state.val + 1});
      console.log(this.state.value); // 第二次输出
      setState は React コンポーネントの state の値をすぐに変更しないため、setState の this.state.value は同じですどちらの場合も同じ値は 0 なので、両方の出力は 0 になります。したがって、値は 1 だけ増加します。
    • この場合、this.stateを直接操作できるでしょうか?例:
    • this.state.value=this.state.value+1;

    • これは確かに this.state.value のステータスを変更できますが、レンダリングを繰り返すことはできません。
    • そのため、React によって設定された setState 関数を通じて this.state を変更し、それによって再レンダリングをトリガーする必要があります。
    • setTimeout の 2 つの setStates:

      setTimeout(() => {
        this.setState({value: this.state.value + 1})
        console.log(this.state.value) // 第三次输出
        this.setState({value: this.state.value + 1})
        console.log(this.state.value) // 第四次输出
      }, 0);
      this.state の値は同時に更新されます
    • 同期更新:

      は ReactEvent 処理によってトリガーされます。 (例: onClick によってトリガーされるイベント処理)、setState を呼び出すと this.state が非同期的に更新されます

    • 非同期更新:

      さらに、setState 呼び出しは this.setState を同期的に実行します。 「さらに」とは、React によって addEventListener を通じて直接追加されたイベント処理関数と、setTimeout/setInterval によって生成される非同期呼び出しをバイパスすることを指します。

    • this.setState更新メカニズム図:

    ReactでのsetStateの使い方の詳しい説明

      setStateが新しい状態を生成するたびに、順番にキューに格納され、isBathingUpdates変数に従って、 this.stateを直接更新するか、それをdirtyComponentで後ほど話しましょう。
    • isBatchingUpdates のデフォルトは false です。これは、setState が this.state を同期的に更新することを意味します。
    • 但是,当React在调用事件处理函数之前就会调用batchedUpdates,这个函数会把isBatchingUpdates修改为true,造成的后果就是由React控制的事件处理过程setState不会同步更新this.state。

    同步更新(函数式setState)

    1. 如果this.setState的参数不是一个对象而是一个函数时,这个函数会接收到两个参数,第一个是当前的state值,第二个是当前的props,这个函数应该返回一个对象,这个对象代表想要对this.state的更改;

    2. 换句话说,之前你想给this.setState传递什么对象参数,在这种函数里就返回什么对象。不过,计算这个对象的方法有些改变,不再依赖于this.state,而是依赖于输入参数state。

    function increment(state, props) {
      return {count: state.count + 1};
    }
    function incrementMultiple() {
      this.setState(increment);
      this.setState(increment);
      this.setState(increment);
    }
    • 假如当前this.state.count的值是0,第一次调用this.setState(increment),传给increment的state参数是0,第二调用时,state参数是1,第三次调用是,参数是2,最终incrementMultiple让this.state.count变成了3。

    • 对于多次调用函数式setState的情况,React会保证调用每次increment时,state都已经合并了之前的状态修改结果。

    要注意的是,在increment函数被调用时,this.state并没有被改变,依然,要等到render函数被重新执行时(或者shouldComponentUpdate函数返回false之后)才被改变。

    同步异步setState的用法混合

    function incrementMultiple() {
      this.setState(increment);
      this.setState(increment);
      this.setState({count: this.state.count + 1});
      this.setState(increment);
    }
    • 在几个函数式setState调用中插入一个传统式setState调用,最后得到的结果是让this.state.count增加了2,而不是增加4。

    • 这是因为React会依次合并所有setState产生的效果,虽然前两个函数式setState调用产生的效果是count加2,但是中间出现一个传统式setState调用,一下子强行把积攒的效果清空,用count加1取代。

    • 所以,传统式setState与函数式setState一定不要混用。

    相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

    推荐阅读:

    JS中使用接口步骤详解

    EasyCanvas绘图库在Pixeler项目开发中使用实战总结

    以上がReactでのsetStateの使い方の詳しい説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明:
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。