MUIのAccordionで3階層チェックリストを作ったときの学び
まえがき
仕事ではスケジュールがカツカツな業務アプリの実装を、
プライベートでは引っ越しをしており、なかなか学習に時間を使えていないのですが、
業務アプリでフロントを実装しているときに、
フロントエンドエンジニアの方に色々教わり、学びがあったのでこれをネタにしたいと思います
どういうことをやろうとしていたのか
このように3階層のチェックリストのモーダルを作ろうとしていました。
コンテンツの数は
1層:約10種類
2層:約10種類
3層:約20種類
合計2,000近いコンテンツになりました。
これを実装するにあたり、躓いた事・解決方法をまとめておきます
学んだこと
Accordionのコンテンツ数が多くてレンダリングが遅くなる
これはMUIのドキュメントにも書かれているんですが、
Accordion
に渡されたコンテンツはサーバー側のレンダリングとSEOを考慮して、デフォルトでは全てマウントしてレンダリングされてしまいます。
そのため、項目数が多いコンテンツはそのレンダリングに数〜数十秒かかります。
実際、自分が実装していた3階層Accordionははじめに書いたように2,000近いコンテンツ数だったため、表示されるのにそれぐらいかかりました。
解決方法
解決方法もちゃんとドキュメントに書かれていました。
Accordion
を展開するタイミングで、その配下の階層がレンダリングされるように次の記述を行うことで解消することができます。
<Accordion TransitionProps={{ unmountOnExit: true }} />
チェックボックスのonClickとAccordionのexpandedが同時に動作する
MUIとreact-hook-formを使って次のような実装をしていたのですが、
<Accordion TransitionProps={{ unmountOnExit: true }}>
<AccordionSummary>
<FormControlLabel
control={
<Controller
control={control}
render={({ field }) => {
return (
<Checkbox
onChange={() => {
}}
/>
);
}}
/>
}
/>
</AccordionSummary>
<AccordionDetails>
</AccordionDetails>
</Accordion>
このとき、チェックボックスのonClick
の判定領域とAccordion
のexpanded
の判定領域が重なっているため、両方発火してチェックが付くのと同時にAccordion
が閉じたり開いたりという事象が発生しました。
解決方法
この問題の解決方法はonClick
のevent
がもつstopPropagation()
で、
親コンポーネント(Accordion)にイベントが伝搬しないようにすることで解決することを教わりました。
<Checkbox
onClick={(e) => e.stopPropagation()}
/>
// または
<FormControlLabel
onClick={(e) => e.stopPropagation()}
/>
おまけ
今作っている業務アプリを通して、
フロントエンドエンジニアの方にReactのFormにはControlledとUncontrolledがあることを教わりました。
react-hook-formはUncontrolledを採用しているそうです。
そういう概念があることは分かったんですが、
自分が知らないところでControlled, Uncontrolledが切り替わってしまい、
エラーが出て悩まされる日々です。
今回の事とこのFormの仕様などを新たに知って、フロントは奥が深いなと痛感しました。
Discussion