エラーメッセージ
Uncaught Error: 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:
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- You might have more than one copy of React in the same app
function componentの中でのみHooksを呼ぶことができますとエラーが出た
問題&解決策
カスタムHook内のcallback関数内でuseXXXを使用していたのが問題でした。
callback関数ではなく1つ外でuseXXXを呼んであげることでエラーが解消しました。
エラーになるコード例
App.tsx
import useTextInput from "./useTextInput";
const App = () => {
const nameInput = useTextInput("");
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
console.log(`Hello, ${nameInput.value}!`);
nameInput.clear();
};
return (
<form onSubmit={handleSubmit}>
<label>
Name:
<input type="text" {...nameInput} />
</label>
<button type="submit">Submit</button>
</form>
);
};
export default App;
hooks.ts
import { useState } from "react";
const useTextInput = (initialValue: string = "") => {
// ここはuseXXXを呼んでも問題ない
const [value, setValue] = useState<string>(initialValue);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
// callback関数の中でhook(useXXX)を使ってしまうとエラーが発生する
const [dummy, setDummy] = useState<string>(initialValue);
setValue(event.target.value);
};
const clear = () => {
setValue("");
};
return {
value,
onChange: handleChange,
clear,
};
};
export default useTextInput;