Parent.tsx
1const Parent:React.FC = ({ children }) => { 2 const [isOpen, setIsOpen] = React.useState(false); 3 4 const childrenWithProps = React.Children.map(children, child => { 5 if (React.isValidElement(child)) { 6 return React.cloneElement(child, { setIsOpen }); 7 } 8 return child; 9 }); 10 return ( 11 <> 12 <Modal open={isOpen} /> 13 {childrenWithProps} 14 </> 15 ); 16};
Child.tsx
1type ChildProps = {setIsOpen: React.Dispatch<React.SetStateAction<boolean>>} 2const Child:React.VFC<ChildProps> = (props) => { 3 return ( 4 <> 5 <button onClick={props.setIsOpen(true)}>開く</button>; 6 <button onClick={props.setIsOpen(false)}>閉じる</button>; 7 </> 8};
App.tsx
1const App = () => { 2 return ( 3 <Parent> 4 <Child /> 5 </Parent> 6 ); 7}
上記コードにおいて、Child
コンポネントで指定しているChildProps
型をany
に変更すると、Child
コンポネント上の開く・閉じるボタンを押すことで Parent
コンポネント上のモーダルを開閉することはできるため、reactの実装としては問題ないように思えます。
しかし、ChildProps
型を上記コードのように指定すると、App.tsx
で<Child />
にsetIsOpen
が渡されていないためエラーとなってしまいます。
どのような型定義をすればよいでしょうか?もしくは実装パターンが間違っているのでしょうか?
実装時はParent
コンポネントを大量に使用したいと考えています。
よって可能であれば、子コンポネント側で都度setIsOpen
あたりをいじらなくてもよいような方法を模索しているのですが、良いアイデアないでしょうか?
追記
私が考えたワークアラウンドとしては
Child.tsx
1type ChildComponent<T> = (props: T & {setIsOpen?: React.Dispatch<React.SetStateAction<boolean>>} => JSX.Element 2const Child: ChildComponent<PropsWithoutSeTIsOpen> = (props) => { 3 return ( 4 <> 5 <button onClick={props.setIsOpen!(true)}>開く</button>; 6 <button onClick={props.setIsOpen!(false)}>閉じる</button>; 7 </> 8};
とすることで型エラーも解消し、機能もしたのですがいかんせんprops.setIsOpen!
が気持ち悪いなというところです。


回答1件
あなたの回答
tips
プレビュー