1. ホーム
  2. ジャバスクリプト

[解決済み】 `useRef` と `createRef` の違いは何ですか?

2022-04-18 21:04:33

質問

フックのドキュメントを読んでいて、次のようなものに出会いました。 useRef .

彼らの例を見てみると...

function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
    // `current` points to the mounted text input element
    inputEl.current.focus();
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}

...のようです。 useRef に置き換えることができます。 createRef .

function TextInputWithFocusButton() {
  const inputRef = createRef(); // what's the diff?
  const onButtonClick = () => {
    // `current` points to the mounted text input element
    inputRef.current.focus();
  };
  return (
    <>
      <input ref={inputRef} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}

なぜrefsのフックが必要なのか?なぜ useRef は存在するのでしょうか?

どのように解決するのですか?

その差は createRef は常に新しいrefを作成します。クラスベースのコンポーネントでは、通常、構築時にインスタンスプロパティにrefを置くことになります(例えば this.input = createRef() ). 関数コンポーネントでは、このオプションはありません。 useRef は、最初のレンダリングのときと同じ参照番号を毎回返すようにします。

この2つの関数の動作の違いを示すサンプルアプリを紹介します。

import React, { useRef, createRef, useState } from "react";
import ReactDOM from "react-dom";

function App() {
  const [renderIndex, setRenderIndex] = useState(1);
  const refFromUseRef = useRef();
  const refFromCreateRef = createRef();
  if (!refFromUseRef.current) {
    refFromUseRef.current = renderIndex;
  }
  if (!refFromCreateRef.current) {
    refFromCreateRef.current = renderIndex;
  }
  return (
    <div className="App">
      Current render index: {renderIndex}
      <br />
      First render index remembered within refFromUseRef.current:
      {refFromUseRef.current}
      <br />
      First render index unsuccessfully remembered within
      refFromCreateRef.current:
      {refFromCreateRef.current}
      <br />
      <button onClick={() => setRenderIndex(prev => prev + 1)}>
        Cause re-render
      </button>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);