generated at
render hooks パターン

react hooksで、コンポーネント(のReact.ReactNode)を返すテクニックのこと
状態とコンポーネントを両方渡す時に便利
↑のLINE証券の記事でuhyo氏がこのパターンを命名してくれたおかげで、ググりやすくなった
これ以前でも、hooksからelement返すのはやったことある人は多分いると思うから起源は分からん
起源は追わなくてもいいかなと思う
命名してくれたことが偉いと思う


ts
const App: React.FC = () => { const [isAllChecked, node] = useChecks(labels) return ( <div> {node} <p> <button disabled={!isAllChecked}>次へ</button> </p> </div> ) }

モーダルの実装なんかも
js
const App: React.FC = () => { const {isOpen, open , node} = useModal() return ( <div> {node} <button onClick={open}>開く</button> </div> ) }


twitterで検索すると、このパターンに対して不安を感じる声がある
hooksは単なる関数であり、ReactElementは単なるJSのオブジェクトに過ぎないので何も問題ない
不安を覚えるなら、そもそもJavaScriptでUIを構築することに不安を覚えても良いのでは?
hooksライブラリからコンポーネントを返したいことはあんまりないので、ライブラリにて採用されてる実例は少ない
このパターンを利用すべきケースは、ライブラリじゃなくてアプリケーション側のほうが発生しやすいと思われる


Element(ReactNode)を返すべきかFC ( ()=>Element )を返すべきか
>@uhyo_: 「hooksからコンポーネントを返す」と言われたときにReact.FCを返すやつとJSX.Elementを返すやつが混同されている懸念がある。ぼくが推してるのはJSX.Elementを返すほうです(?)
>@uhyo_: React.FCを返すほうはあまり良くないと思う。というのもステートを内包させると必然的にステートが変わると別の関数オブジェクトになり、再レンダリング時にパフォーマンスのペナルティがあるから🫐
たしかにmiyamonz
でもLINE証券の記事では後者なんだな
Element直返しで良いと思ってるが、何か後から渡す引数があるなら、(arg)=>Elementでもいいだろう

この記事にもあるように、結局FC(関数)を渡せば、それはobjectの同一性においてレンダリングのたびに異なるelementが作られうるので、基本はelementを返すのが正しい


ここで紹介されてるreact-hooks-use-modalもこのパターンと言える
こっちはFCを返してる


>@uhyo_: そうだな。childrenは特殊な構文を与えられたrender propsであると考えたほうが幸せになりそう。レイアウトの責務を持つコンポーネントだとslotが1つだと普通に足りないときがあるし(?)
そのとおりすぎて、childrenがReactNodeなのだから、別のpropにわたす変数もReactNode(Element)で保持して良いに決まってるmiyamonz


そもそも、react elementを普段遣いのオブジェクトとして触りつつ、それを関数で返すようになると勝手にrender hooksになる
ただし厳密には、内部にuseState, useEffectなどが無いようなものは、hooksでは無く単なる関数で
コンポーネントレンダリング時にif文で分岐させてはいけない系の制約もなくなる




記事
fileのinput要素と、渡されたdataURLを返す
useStateのsetをコンポーネントとして受け取ると考えるとたしかにこれは良いか
値をユーザから受け取って、必要な情報を取り出すというロジックをrender hooks内に閉じ込められる、と考えられる
さらに、プレビュー画面もコンポーネントにしてしまうのも書いている

良く考えたらそりゃそうだなmiyamonz
しかし、これが当たり前、と言えるのはReactをある程度習熟してないとむずそうだな

あまり海外の文献は見当たらない