web-dev-qa-db-ja.com

React.useStateはどのように再レンダリングをトリガーしますか?

_import { useState } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
_

上記の例では、setCount(count + 1)が呼び出されるたびに再レンダリングが発生します。流れを知りたいです。

ソースコードを調べてみました。 github.com/facebook/reactuseStateまたは他のフックの参照を見つけることができませんでした。

_react@next_を介して_npm i react@next_をインストールし、_node_modules/react/cjs/react.development.js_で以下を見つけました

_function useState(initialState) {
  var dispatcher = resolveDispatcher();
  return dispatcher.useState(initialState);
}
_

dispatcher.useState()を逆にたどると、次のものしか見つかりませんでした...

_function resolveDispatcher() {
  var dispatcher = ReactCurrentOwner.currentDispatcher;
  !(dispatcher !== null) ? invariant(false, 'Hooks can only be called inside the body of a function component.') : void 0;
  return dispatcher;
}
_
_var ReactCurrentOwner = {
  /**
   * @internal
   * @type {ReactComponent}
   */
  current: null,
  currentDispatcher: null
};
_

dispatcher.useState()実装はどこにありますか? setState setCountが呼び出されます。

どんなポインタも役に立ちます。

ありがとう!

16
sarbbottam
2
sarbbottam

setStateComponent/PureComponentクラスのメソッドであるため、Componentクラスで実装されているすべてのことを実行します(renderメソッドの呼び出しを含む)。

setStateは、状態の更新をenqueueSetStateにオフロードするため、これにバインドされているという事実は、クラスを使用し、Componentから拡張した結果にすぎません。一度、状態の更新は実際にはコンポーネント自体によって処理されておらず、thisは状態の更新機能にアクセスするための便利な方法であり、useStateは明示的にバインドされていないことがわかりますあなたのコンポーネントはもっと理にかなっています。

3

FunctionComponentが異なります。以前は、それらは純粋で単純です。しかし今、彼らは彼ら自身の状態を持っています。 createElementがすべてのJSXノードをラップし、FunctionComponentも含まれていることを忘れるのは簡単です。

function FunctionComponent(){
  return <div>123</div>;
}
const a=<FunctionComponent/>
//after babel transform
function FunctionComponent() {
  return React.createElement("div", null, "123");
}

var a = React.createElement(FunctionComponent, null);

FunctionComponentが反応のために渡されました。 setStateが呼び出されると、簡単に再レンダリングできます。

0
高学远