コンポーネント A がコンポーネント B を使う
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 の方法がべスト?