6
2

More than 3 years have passed since last update.

reduxのstoreの値をpropsで受け渡ししない方が良い

Posted at

最初に

react-reduxのパフォーマンスについての記事です。

問題となるコード

console.log(store.getState())
//{
//  childState1:"hoge"
//  childState2:"fuga"
//}

const ParentComponent = () => {
  const storeState = useSelector(state=>state);
  return (
    <>
      <ChildComponent text={state.childState1}/>
      <ChildComponent text={state.childState2}/>
    </>
  );
}

const ChildComponent = ({text}) => {
  return(
    <div>{text}</div>
  )
}

何が問題なのか

storeStateChildComponentのための値なのに、ParentComponentのStateとして扱われます。
(厳密にはstateではありませんが、わかりやすくするためにstateとさせてください)

もし、childState1もしくは、childState2のどちらかの値が更新されると、ParentComponentと二つのChildComponentすべてが再レンダリングされてしまいます。

再レンダリングされるコンポーネントが多くなれば、それだけパフォーマンスも悪くなります。

修正


const ParentComponent = () => {
  return (
    <>
      <ChildComponent objKey={"childState1"}/>
      <ChildComponent objKey={"childState2"}/>
    </>
  );
}

const ChildComponent = ({objKey}) => {
  const text = useSelector(state=>state[objKey]);
  return(
    <div>{text}</div>
  )
}

useSelecotorが多く実行されることは問題ではないのか

まず、useSelectorの仕組みについて説明します。

const storeState = useSelector(state=>state)

アセット 1.png
storeは値が変更されるとuseSeletorによって登録されたListenerを使ってuseSelectorに通知します。
useSelectorは新しい値と古い値を比較し、違いがあればコンポーネントを再レンダリングします。

ここで、問題となるのがuseSelectorが登録するlistenerの処理量と再レンダリングされるreactコンポーネントの処理量です。
知っての通り、Reactコンポーネントを再レンダリングすると処理量が大きくなります。
useSelectorではlistenerの登録、値の比較、更新のみの処理となります。

よって、storeの値はpropsで受け渡しするよりもuseSelectorで直接取得した方が、パフォーマンスが良くなります。

6
2
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
6
2