2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

callback形式refってちょっときになるやつをやってみる

Posted at

概要

React hooksのドキュメントを眺めていたら、ちょっと気ななるuseRefの使い方が書かれていた。
いつどんな状況で使えるのかも含めて書いていく。

なにをしたいやつか

リファレンスを見ている限り、refで指定しているコンポーネントがマウントされたタイミングで実行できる関数をrefに書くことができるように見えた。

export default function App() {
  const callbackref = useCallback(() => console.log("appのref"), []);
  return <div ref={callbackref} className="App" />;
}

// appのref 

再レンダリングされたとき

再レンダリングされたときは、もう一回関数が実行されるか試してみる。
予想:実行される

export default function App() {
  // 再レンダリング用
  const [state, setState] = useState(false);
  const toggleState = useCallback(() => setState(!state), [state]);
  console.log({ state });

  const callbackref = useCallback(() => console.log("appのref"), []);
  return (
    <div ref={callbackref} className="App">
      <button onClick={toggleState}>toggle</button>
    </div>
  );
}

Mar-28-2020 23-43-33.gif

予想と違って、初回のレンダリングときだけ処理されるようだ。

子ノードにも持たせてみる

子のノードにもcallbackrefを渡したときはどんな順番で処理されるのか見てみる
予想:親→子の順番

export default function App() {
  // 再レンダリング用
  const [state, setState] = useState(false);
  const toggleState = useCallback(() => setState(!state), [state]);
  console.log({ state });

  const callbackref = useCallback((node) => console.log(node), []);
  return (
    <div ref={callbackref} className="pearent">
      <div ref={callbackref} className="child" />
      <button onClick={toggleState}>toggle</button>
    </div>
  );
}

image.png

これも予想とは違い、子→親の順番で処理された。
これはの順番もあるかもだけど、レンダリング処理が終わった順番から処理されるのかもしれない。

useEffectと比べて

useEffectの処理との順番を見る
予想:子→親→useEffect

export default function App() {
  // 再レンダリング用
  const [state, setState] = useState(false);
  const toggleState = useCallback(() => setState(!state), [state]);
  
  useEffect(() => {
    console.log('useEffect');
  }, []);

  const callbackref = useCallback((node) => console.log(node), []);
  return (
    <div ref={callbackref} className="pearent">
      <div ref={callbackref} className="child" />
      <button onClick={toggleState}>toggle</button>
    </div>
  );
}

image.png

これは予想通り、最後にuseEffectの処理が来た。

ここまででわかったこと

最初に述べたように、書くrefのノードがマウントされたあとにだけ処理されるようだ。

今まで、ノードに対して直接処理をしたい場合はuseEffectに書いていたんだが、これを使えば、useEffectを書かずとも、そのノードのrefに書いてあげればうまく動いてくれることがわかった。

使いみち

そして使いみちだけど、正直なにも思いつかないw
ライブラリ作るときとか、ちょっとこったUI作ったりするときは使うのかもしれないが、ちょっと考えつかない。。。

もしこんなので使ってるよみたいなのがあったら教えてほしいです。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?