tgoop.com/prog_way_blog/253
Create:
Last Update:
Last Update:
Как сохранять состояние в URL
В одном из прошлых постов я рассматривал требования к стажировке в Авито. Одним из требований к тестовому было кешировать значения в URL, в этом посте рассмотрим это более подробно и сделаем самую простую реализацию такого функционала.
Представим, что у нас есть строковый инпут для имени пользователя, его состояние в URL может выглядеть следующим образом:
www.site.com/?name=progway
Соответственно, нам нужен инструмент, который позволит управлять этим состоянием. Как бы хотелось это видеть? Лично мне — ровно так же, как работает и обычный
useState
. Тогда от этого и будем отталкиваться:const [name, setName] = useQueryState("name");
const [surname, setSurname] = useQueryState("surname", "Putnov");
Первым аргументом будем указывать ключ в URL, а вторым — изначальное состояние. Далее рассмотрим внутреннюю имплементацию хука и начнём с его интерфейса, тут всё достаточно просто:
type QueryValue = string | undefined;
function useQueryState<I extends QueryValue>(
queryKey: string,
defaultValue?: I,
) {
// тело хука
}
Реализуем наш собственный хук на базе
useSearchParams
из react-router-dom
для удобного доступа к состоянию URL-a. Если вы используете другой роутинг, можно использовать аналогичный механизм, который подойдёт именно в вашем проекте. Мы же будем его использовать для изменения URL-a и восстановления состояния из URL-a при маунте компонента. Если в URL-е уже есть состояние, мы будем использовать его. Если нет, будем использовать defaultValue
:const [searchParams, setSearchParams] = useSearchParams();
const [state, setState] = useState<QueryValue>(() => {
const targetValue = searchParams.get(queryKey);
if (targetValue !== null) {
return targetValue;
}
return defaultValue;
});
Ну а всё что нужно далее — реагировать на изменение состояния и обновлять URL в соответствии с ним. Если в инпуте вдруг окажется пустая строка, то мы просто удалим наше состояние из Query параметров
useLayoutEffect(() => {
setSearchParams((prev) => {
if (state) {
prev.set(queryKey, state);
} else {
prev.delete(queryKey);
}
return prev;
});
}, [state, queryKey, setSearchParams]);
Да и всё. Всё работает.
Вот весь код, который, конечно же, не идеальный. Смысл поста — отразить основную суть.
Спасибо за прочтение, это важно для меня ❤️
@prog_way_blog — чат — #theory #code #typescript #web #react
BY progway — программирование, IT
Share with your friend now:
tgoop.com/prog_way_blog/253