~共通フォーム type Props = { submitButton: (props: { onSubmit: (callback: (data: { name: string; hobby: string }) => void) => void }) => React.ReactNode } const ProfileForm = ({ submitButton }: Props) => { const [name, setName] = useState('') const [hobby, setHobby] = useState('') const handleFormSubmit = (callback: (data: { name: string; hobby: string }) => void) => { if (!validate()) return // バリデーション発火 callback({ name, hobby }) } return ( <div> <input value={name} onChange={e => setName(e.target.value)} placeholder="名前" /> <input value={hobby} onChange={e => setHobby(e.target.value)} placeholder="趣味" /> {submitButton({ onSubmit: handleFormSubmit })} </div> ) } 具体的に共通化している: - フォームの入力状態 - バリデーションロジックと発火タイミ ング - パーツの位置関係 抽象定義しておき、使う側で注入する: - submitのUI - バリデーション後の処理 submitButtonはReact.ReactNodeで受 け取るのではなく 「() => React.ReactNode」レンダーに する。