0
0

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 1 year has passed since last update.

[React] Component を再レンダリングさせない!

Posted at

Reactにおける再レンダリング

Reactで各compnentが再レンダリングされてしまう条件は以下の3つです。

  1. stateの更新
  2. propsの更新
  3. 親component の更新

1,2はいいでしょう。定義したstateやpropsが変化すれば当然componentは変化してほしいわけです。
(stateやpropsがバケツリレーされていないのが前提。もしその場合はグローバルな値にするとか別の方法探してください。)

問題は3です。
親componentを更新したいだけなのに、その中に含まれる子component(以下孫、ひ孫....)まで更新されちゃたまったもんじゃないですよね。
折角Reactで書いてるんだから、そんないかにも重くなりそうなことしたくない。。。

#そんな時には!
そんな問題を解決するためにはメモ化!

##memo

memoの使用
export const ExComponent = memo((props) => { return (hogehoge) })

memo()で括ってやれば、親componentの更新影響を受けなくなります。

いや待ってくれ!memo化しても更新されたぞ??嘘つきか?

例えばこんなcomponent。

App.jsx
export default function App() {
  const [exText, setExText] = useState("");

  const changeExText = (e) => {
    setExText(e.target.value);
  };

  return (
    <>
      <Child changeText={changeText} />
    </>
  );
}
Child.jsx
const Child = memo((props) => {
  const { changeExText } = props;
  return (
    <>
      <input type="text" onChange={changeExText} />
    </>
  );
});

親Componentで設定した関数を子Componentに受け渡して処理。
でも必要なステートは親の中だけだし、更新されるのは親だけと思っていたら、この場合、親子どちらも更新される。
memo化はしたのだが。。。

関数のメモ化はuseCallbackを使え

上記の原因はズバリpropsで受け渡した関数。
親コンポーネントのpropsで子コンポーネントに関数を渡すと、関数の内容が同じでも子コンポーネントでは「毎回新しい関数が渡されている」と判断されてしまうらしい。まあ確かにそう見える。。。

そんな時にuseCallbackの出番。

App.jsx
const changeExText = useCallback(
    (e) => {
      setExText(e.target.value);
    },
    [setExText]
  );

useCallbackを使えば上記のような再レンダリングは起こらない。
使い方はuseEffectと同様なので、簡単だ。

まとめ

できるだけ重くないreactを書きたい時にはmemo/useCallbackを駆使して再レンダリングをできるだけ抑えるべし。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?