Next.jsでフォームの値を復元するには
27343 ワード
React RouterとNext.jsの違い
次のようなフォームの機能を考える。
- フォーム入力
- フォーム確認画面
- フォーム入力に戻る。このとき入力したものは残る。
2→3においてReact Routerを使う場合はlocation.stateに入力した値を保存して取りまわせるが、Next.jsでは類似の機能がないのでクエリパラメータに格納する。
以下、概要のコード:
カスタムフック
useQueryState.ts
const hasKeys = (object: Record<string, unknown>, keys: string[]) => {
for (const key of keys) {
const valid = Object.prototype.hasOwnProperty.call(object, key);
if (!valid) return false;
}
return true;
};
/**
* Set initial state from query object.
*
* @param defaultState Default state when empty or invalid query.
*/
const useQueryState = <T extends Record<string, string>>(defaultState: T) => {
const { query } = useRouter();
const [values, setValues] = useState<T>(defaultState);
useEffect(() => {
if (hasKeys(query, Object.keys(defaultState))) {
setValues(query as T);
}
}, [defaultState, query]);
return [values, setValues] as const;
};
export default useQueryState;
stateをrouter.queryと紐付ける。指定のキーがあればそれを適用、なければデフォルト値にセット。
フォーム
type Values = {
username: string;
comment: string;
};
const initialValues: Values = {
username: "",
comment: "",
};
const Home: NextPage = () => {
const router = useRouter();
const [values, setValues] = useQueryState(initialValues);
const handleChange = (e: React.ChangeEvent<any>) => {
setValues((prevValues) => ({
...prevValues,
[e.target.name]: e.target.value,
}));
};
const handleSubimit = (e: React.FormEvent<any>) => {
e.preventDefault();
router.push({
pathname: "/confirm",
query: values,
});
};
return (
<div>
<Head>
<title>Post</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
<h1>Post</h1>
<form onSubmit={handleSubimit}>
<div>
<label htmlFor="username">username</label>
<input
type="text"
id="username"
name="username"
value={values.username}
onChange={handleChange}
/>
</div>
<div>
<label htmlFor="comment">comment</label>
<input
type="text"
id="comment"
name="comment"
value={values.comment}
onChange={handleChange}
/>
</div>
<button>Post</button>
</form>
</main>
</div>
);
};
export default Home;
フォーム確認画面
const Confirm: NextPage = () => {
const router = useRouter();
const goBack = () => {
router.push({
pathname: "/",
query: router.query,
});
};
return (
<div>
<Head>
<title>Confirm</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
<h1>Confirm</h1>
<ul>
<li>username: {router.query.username}</li>
<li>comment: {router.query.username}</li>
</ul>
<button onClick={goBack}>Back</button>
</main>
</div>
);
};
export default Confirm;
Author And Source
この問題について(Next.jsでフォームの値を復元するには), 我々は、より多くの情報をここで見つけました https://zenn.dev/yhase_rqp/articles/6230dbb9453fd2著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Collection and Share based on the CC protocol