今でもスッキリしない React での初期化処理の扱い方

const Component = (props) => {
// ...

return (
<div>
<Edit
value={value}
onChange={onChange}
/>
</div>
)
}

Edit コンポーネントがあって何かを編集するものです
React なので value を渡して編集があれば onChange で受け取って親側で更新するという 親側で state を管理する作りです
これだと value の値を初期化やチェックして修正するときに親側でやらないといけなくなります
ですが そのロジックは Edit のものなので Edit でやってもらいたいです
そうなると ユーザーの操作なしで Edit のマウント時に onChange を呼び出して更新することになります
仕方ないのですがそれはなんか気持ち悪さがあります

親で state 管理しないものなら 初期値を渡すだけで修正した値は Edit の中で持っておいて 親が値を使いたいときに Edit から取り出します
これだと自然なのですよね

Edit コンポーネントのモジュールから関数もエクスポートすれば ロジックは Edit モジュールの中で持てます
しかし Edit を使うのに 初期値を作る部分とコンポーネント部分で 2 つの処理が必要になるのが面倒です
例えば API で選択肢を取得して初期値が null なら最初の選択肢を初期値にする場合 初期値のために関数で API を呼び出して コンポーネント内でも選択肢を作るために API を呼び出す必要があるので 関数とコンポーネントの両方で API を呼び出すことになります
それを避けるなら関数は初期値の他に選択肢も返して それもコンポーネントに渡すという作りになりますが やることが増えます
やりたいのは単純に Edit コンポーネントを使って props を渡すだけにしたいのですけど

onChange の場合でも困るところはあります
変更イベントを beforeunload などと関連付けていれば ユーザーは何も編集してないのに変更ありとして扱われます
初期化が null の場合に値を入れたり 不正文字を除去など繰り返し行っても問題ないものならいいですが そうでない場合は判断するのが難しいです
入力値を制御するライブラリでは onChange を即呼び出すものを見かけますが 組み合わせるライブラリの相性とかもあるのか ときどきうまく動いてなかったりするのですよね
レンダリング中に同期的に呼び出すと問題ありそうですし useEffect 通しても その他の useEffect との順序が影響しそうです