この記事では、「useQueryState」というカスタムフックを使用して、Next.jsアプリケーションでクエリ文字列と状態を同期化する方法を紹介します。このフックは、クエリ文字列の変更に対して状態を自動的に更新し、状態の変更に対してクエリ文字列を更新する機能を提供します。
まず、次のように「useQueryState」フックを実装します。
import { useState, useEffect } from 'react';
import { useRouter } from 'next/router';
function useQueryState(key, defaultValue) {
const router = useRouter();
const [value, setValue] = useState(defaultValue);
useEffect(() => {
const queryValue = router.query[key];
if (queryValue !== undefined) {
setValue(queryValue);
}
}, [router.query[key]]);
useEffect(() => {
const query = { ...router.query };
if (value === defaultValue) {
delete query[key];
} else {
query[key] = value;
}
router.push({ pathname: router.pathname, query });
}, [value]);
return [value, setValue];
}
このカスタムフックは、指定されたキー(クエリ文字列の名前)とデフォルト値を受け取ります。フック内で、ReactのuseState
フックとuseEffect
フックを使用して状態を管理し、useRouter
フックを使用して現在のクエリ文字列を取得します。
次に、状態の変更とクエリ文字列の変更を監視するために、2つのuseEffect
フックを使用します。1つ目のuseEffect
フックでは、クエリ文字列が変更された場合に状態を更新します。2つ目のuseEffect
フックでは、状態が変更された場合にクエリ文字列を更新し、ページのURLを変更します。
このカスタムフックを使用するには、次のようにコンポーネント内で呼び出します。
import { useRouter } from 'next/router';
import useQueryState from 'path/to/useQueryState';
function MyComponent() {
const router = useRouter();
const [search, setSearch] = useQueryState('search', '');
const handleSearchChange = (e) => {
setSearch(e.target.value);
};
return (
<div>
<input type="text" value={search} onChange={handleSearchChange} />
<button onClick={() => router.push({ pathname: router.pathname, query: { search } })}>
Search
</button>
</div>
);
}
上記の例では、useQueryState
フックを使用して、search
というクエリ文字列を状態として管理しています。search
の値が変更されると、自動的にクエリ文字列が更新され、URLが変更されます。
このようにして、「useQueryState」フックを使用することで、Next.jsアプリケーションでクエリ文字列と状態を簡単に同期化することができます。これにより、URLパラメータの変更に応じてコンポーネントの表示や振る舞いを制御することができます。また、クエリ文字列と状態の同期化は、ブラウザの履歴管理やブックマーク機能との統合にも役立ちます。
さらに、このカスタムフックを応用して、他のクエリ文字列と状態を同期化する方法もあります。例えば、ページネーションやフィルタリングのためのクエリパラメータを状態として管理することができます。
以下に、他のクエリ文字列と状態を同期化する例を示します。
import { useRouter } from 'next/router';
import useQueryState from 'path/to/useQueryState';
function MyComponent() {
const router = useRouter();
const [page, setPage] = useQueryState('page', 1);
const [category, setCategory] = useQueryState('category', 'all');
const [sortBy, setSortBy] = useQueryState('sortBy', 'date');
const handlePageChange = (newPage) => {
setPage(newPage);
};
const handleCategoryChange = (newCategory) => {
setCategory(newCategory);
};
const handleSortByChange = (newSortBy) => {
setSortBy(newSortBy);
};
return (
<div>
<div>Page: {page}</div>
<button onClick={() => handlePageChange(page + 1)}>Next Page</button>
<div>Category: {category}</div>
<select value={category} onChange={(e) => handleCategoryChange(e.target.value)}>
<option value="all">All</option>
<option value="category1">Category 1</option>
<option value="category2">Category 2</option>
</select>
<div>Sort By: {sortBy}</div>
<select value={sortBy} onChange={(e) => handleSortByChange(e.target.value)}>
<option value="date">Date</option>
<option value="name">Name</option>
</select>
<button onClick={() => router.push({ pathname: router.pathname, query: { page, category, sortBy } })}>
Apply Filters
</button>
</div>
);
}
この例では、page
、category
、sortBy
という3つのクエリパラメータを状態として管理しています。それぞれの状態が変更されると、クエリ文字列が自動的に更新されます。また、それぞれの状態の変更に応じて、表示やフィルタリングのロジックを適用することができます。
以上が、「useQueryState」フックを使用してNext.jsアプリケーションでクエリ文字列と状態を同期化する方法の紹介です。このフックを使うことで、クエリ文字列と状態の管理を簡単に行うことができます。