Open4

React の コンポジション vs 継承 ってPropsにもあるよねという話

kondeikondei

例えば Library というコンポーネントを使ったりラップする Wrapper というコンポーネントを作るとき、LibraryのPropsを

type LibraryProps = {
  x: string;
};

としたとき、WrapperのPropsの型を

type Props = {
  a: string;
} & LibraryProps;

interface Props extends LibraryProps {
  a: string;
}

のように継承でPropsを作ってWrapper用のPropsとLibraryのPropsを同階層に混ぜてしまい、

const Wrapper: FC<Props> = (props) => <div><Library x={props.x}/></div>;

のように構成するのは拡張性が悪いと思う

kondeikondei

より良い形はPropsもコンポジションにした

type Props = {
  a: string;
  libraryProps: LibraryProps;
}

const Wrapper: FC<Props> = (props) => <div><Library {...props.libraryProps}/></div>;

だと思う

kondeikondei

この方式のデメリットはObject Propsが毎回新しいのでrendering対象になり、更にデフォルトのshallowな比較関数によるmemo化ができないことで、ちゃんとdeepEqualしないと

https://qiita.com/sakamotoryouta/items/938717b4fb1d878be648

のようにrenderingが増えること

将来的には

https://zenn.dev/akfm/articles/7839e093decd08

のようにimmutable構造が追加されたり、

https://www.reddit.com/r/reactjs/comments/rcn5ks/react_forget_compiler_automated_memoization_react/

のようにReact memoを自前で管理する必要がなくなれば楽に解決するかもしれない