B は固定ではなくて使う側で差し替えたい
A の props で B のコンポーネントを受け取るようにする
const ComponentA = ({ ComponentB, componentBProps }) => {
return (
<div>
<ComponentB foo="bar" {...componentBProps} />
</div>
)
}
<ComponentA ComponentB={Foo} componentBProps={{ additional: "a" }} />
A にコンポーネントとそれに渡す props を別に渡すよりは render 関数を渡すほうが便利そう?
const ComponentA = ({ renderB }) => {
return (
<div>
{renderB({ foo: "bar" })}
</div>
)
}
<ComponentA
renderB={
(props) => (<ComponentB {...props} additional="a" />)
}
/>
A が B を直接使うのは A から B へ props を渡したいから
それが入力されたものや選択されたものなら A で持たず A の親で管理することもできる
そうすれば B はコンポーネントではなく Element として A に渡せる
const ComponentA = ({ elementB, onChange, value }) => {
return (
<div>
{elementB}
</div>
)
}
const [state, setState] = useState()
<ComponentA
value={state}
onChange={setState}
elementB={
<ComponentB {...state} additional="a" />
}
/>
でもこうすると B に渡すための state 管理を A を使う側のコンポーネントでしないといけない
A を使う箇所すべてでやるのはつらいのでまとめたい
コンポーネントにすると
const ComponentAB = ({ createElementB }) => {
const [state, setState] = useState()
return (
<ComponentA
value={state}
onChange={setState}
elementB={createElementB(state)}
/>
)
}
<ComponentAB
createElementB={
(props) => (<ComponentB {...props} additional="a" />)
}
/>
まとめたコンポーネント AB に対して ComponentB を使うことを伝えないといけない
renderB を使うケースと同じことになる
A が内部で state を持たなくて AB に移っただけ
再レンダリングの範囲で考えると A だけに収まってたほうが効率は良かった
hook にすると
const useComponentA = (createElementB) => {
const [state, setState] = useState()
return {
value: state,
onChange: setState,
elementB: createElementB(state),
}
}
const componentAProps = useComponentA(
state => (<ComponentB {...state} additional="a" />)
)
<ComponentA {...componentAProps} />
コンポーネントよりマシかと思ったけどあまり変わってない
コンポーネントと hook をペアにしないといけないし
state が A を使うコンポーネントに属することになる
再レンダリング的には影響する範囲が広くなっててコンポーネントの方がまだ良かったかも
ということは renderB の方法がべスト?