最近TypeScriptを学び始め、TypeScript+React HooksでWebアプリを作っています。
その中で、コーディングミスを減らす為にとあるフックの引数を型安全にするためにラップ関数を作りたいと考えました。
しかし、フックを呼び出せるのはトップレベルまたはカスタムフックのみという制約から、フックのラッパをうまく定義することができませんでした。
フックをラップして型安全にする、または同等の処理を実現する方法などありましたらご教示いただきたいです。
以下その制約を回避するために行った試行錯誤です。(ちなみに今回対象のフックはreact-router-domのuseHistoryです)
該当フックを2重にラップするパターン
TypeScript
1const useRedirect = () => (nextPage: '/' | '/about') => useHistory().push(nextPage);
しかし、こちらのパターンはフックの制約から下記エラーで弾かれてしまいます。
Error
1React Hook "useHistory" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function react-hooks/rules-of-hooks
該当フック直接呼び出すパターン
TypeScript
1const useRedirect = (nextPage: '/' | '/about') => useHistory().push(nextPage);
こちらは呼び出し元のトップレベルで実行する場合は問題ありませんが、コールバックの中などから呼び出すと下記エラーで弾かれました。
Error
1React Hook "useRedirect" is called in function "myCallback" which is neither a React function component or a custom React Hook function react-hooks/rules-of-hooks
ラッパの内側の関数をカスタムフックに見せかけるパターン
TypeScript
1const useRedirect = () => function useR(nextPage: '/' | '/about') { useHistory().push(page) };
こちらコンパイルは通りましたが、結局入れ子にした関数からフックを呼び出している状態のため実行時に下記エラーとなりました。
コンパイラを騙して実行時にエラーを残したので一番悪いパターンです。
Error
1Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 21. You might have mismatching versions of React and the renderer (such as React DOM) 32. You might be breaking the Rules of Hooks 43. You might have more than one copy of React in the same app 5See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.
回答2件
あなたの回答
tips
プレビュー