img や iframe などを見ると URL だけ渡せば後はやってくれます
データを取得するのもコンポーネントに任せたいところです
ただ取得もやると 1 コンポーネントが重たくなるなーと思ったり
またデータはすでに別の理由で手元にあるときがあり そういうときでも URL から再取得するのはムダです
取得と使用で分けようかなと思ったものの どうしようか
書きやすさ的に React で考えます
React ならとりあえずフックでしょうか
フックがデータを取得し それを渡します
const data = useData(url)
return data.state === "loaded"
? <DataViewer data={data.content} />
: <Loader />
コンポーネントとして考えると取得するコンポーネントの props に取得したデータを使用するコンポーネントを渡すとかでしょうか
<FetchData url={url} Viewer={DataViewer} />
DataViewer に追加の props も渡したいことを考えると render 関数として渡す方がよいかもしれないです
内側に表示するものなので見た目的に children として渡します
<FetchData url={url}>
{data => <DataViewer data={data} />}
</FetchData>
これらだとすでにデータを取得している場合は DataViewer だけを使うことができます
反対に DataViewer の方を外側に持ってきて FetchData を渡す方法も考えられます
<DataViewer FetchData={FetchData} />
DataViewer が内部で FetchData へ onData 関数を渡して これが呼び出されたら自身の state に受け取ったデータをセットする感じです
FetchData は中でデータを取得し 取得したら props で受け取った onData 関数を呼び出します
DatViewer の props に data も用意してこっちがあればそのデータを使い なければ FetchData を使ってデータを取得とできます
この場合はわざわざ FetchData をコンポーネントにする必要もないので fetch に関数を渡すだけでもいいと思います
<DataViewer fetch={fetchData} />
ただこうするとイベント時の処理ではなく 自身で関数を呼び出すわけなので API を直接呼び出すのと大差ないです
useEffect とかが入ってきます
API を直接呼び出すのと比べて 受け取ったあとのフォーマットやエラー時の処理などをやらなくて済むくらいです
となると FetchData を外側に持ってくるものか フックを使うものです
子コンポーネントに渡すレンダー関数を渡すというのは React ならではのものなので フックの方でしょうか
フックも React 固有になるので実際にはただの関数として用意するようになりそうです
エラー表示を考えるとコンポーネントである FetchData の方が表示も管理できて便利かもしれません
ただエラー表示が固定であればです
使う側でカスタムするなら 結局エラー表示を制御するのでそれなら 関数にしてもいいかもです
ただデータの管理を親コンポーネントでしないといけなくなるので DataViewer がいっぱいあるところだと 使うほうが面倒にもなります
難しいですね