Apabila membina aplikasi React, selalunya berfaedah untuk menggambarkan keadaan dalam URL. Ini bukan sahaja menjadikan negeri boleh dikongsi tetapi juga membenarkan pengguna menanda halaman atau memuat semula halaman tanpa kehilangan konteksnya. Dalam siaran ini, kami akan mencipta cangkuk React tersuai yang dipanggil useParamState dalam TypeScript. Cangkuk ini akan berfungsi seperti useState, tetapi ia juga akan menyegerakkan keadaan dengan parameter carian dalam URL. Yang penting, ia akan menyokong nilai objek yang kompleks.
Kait penggunaanSearchParams React Router sangat baik untuk mengurus parameter carian URL, tetapi menyegerakkannya dengan keadaan komponen boleh menyusahkan. Cangkuk useParamState menangani perkara ini dengan:
( Ini mengandaikan anda sudah tahu cara menyediakan projek tindak balas, jika tidak pergi ke Vite)
Pastikan anda telah memasang react-router-dom:
npm install react-router-dom
Begini cara anda boleh melaksanakan cangkuk useParamState:
import { useCallback, useState } from 'react'; import { useSearchParams } from 'react-router-dom'; /** * A custom hook that syncs state with a URL search parameter. * Supports string, number, boolean, and object values. * @param key The search parameter key to sync with. * @param defaultValue The default value for the state. * @returns A stateful value, and a function to update it. */ function useParamState<T extends string | number | boolean | object>( key: string, defaultValue: T ): [T, (newValue: Partial<T> | T) => void] { const [searchParams, setSearchParams] = useSearchParams(); const paramValue = searchParams.get(key); const [state, setState] = useState<T>(() => { if (paramValue === null) { return defaultValue; } try { return JSON.parse(paramValue) as T; } catch { return paramValue as T; } }); const setParamState = useCallback( (newValue: Partial<T> | T) => { const updatedValue = typeof newValue === 'object' && !Array.isArray(newValue) ? { ...state, ...newValue } : newValue; setState(updatedValue as T); const newSearchParams = new URLSearchParams(searchParams); newSearchParams.set(key, JSON.stringify(updatedValue)); setSearchParams(newSearchParams); }, [key, searchParams, setSearchParams, state] ); return [state, setParamState]; } export default useParamState;
Cangkuk bermula dengan menyemak sama ada parameter carian yang ditentukan wujud dalam URL. Jika ia berlaku, cangkuk menghuraikannya dan menggunakannya sebagai keadaan awal. Jika tidak, ia akan kembali kepada nilai lalai yang disediakan.
Fungsi setParamState mengemas kini kedua-dua keadaan dalaman dan parameter carian dalam URL. Ia menggunakan JSON.stringify untuk mensiri keadaan, membolehkan kami menyimpan objek kompleks dalam URL.
Cangkuk menyokong pelbagai jenis (rentetan, nombor, boolean dan objek) dengan memanfaatkan generik TypeScript dan penghuraian JSON.
Mari lihat bagaimana anda boleh menggunakan useParamState dalam komponen React:
import React from 'react'; import useParamState from './useParamState'; interface FilterState { status: string; sortBy: string; } const MyComponent: React.FC = () => { const [filter, setFilter] = useParamState<FilterState>('filter', { status: 'all', sortBy: 'date', }); return ( <div> <h2>Current Filter: {filter.status}, Sort by: {filter.sortBy}</h2> <button onClick={() => setFilter({ status: 'active', sortBy: filter.sortBy })}> Active </button> <button onClick={() => setFilter({ status: 'completed', sortBy: filter.sortBy })}> Completed </button> <button onClick={() => setFilter({ ...filter, sortBy: 'priority' })}> Sort by Priority </button> </div> ); }; export default MyComponent;
Untuk memastikan cangkuk useParamState berfungsi seperti yang diharapkan, anda boleh menulis ujian unit menggunakan @testing-library/react:
import { renderHook, act } from '@testing-library/react'; import { MemoryRouter } from 'react-router-dom'; import useParamState from './useParamState'; interface FilterState { status: string; sortBy: string; } test('should sync object state with search params', () => { const wrapper = ({ children }: { children: React.ReactNode }) => ( <MemoryRouter initialEntries={['/']}>{children}</MemoryRouter> ); const { result } = renderHook(() => useParamState<FilterState>('filter', { status: 'all', sortBy: 'date' }), { wrapper }); // Initial state expect(result.current[0]).toEqual({ status: 'all', sortBy: 'date' }); // Update state and URL act(() => { result.current[1]({ status: 'active', sortBy: 'priority' }); }); // Updated state expect(result.current[0]).toEqual({ status: 'active', sortBy: 'priority' }); });
Kait useParamState memudahkan proses keadaan penyegerakan dengan parameter carian URL, menjadikan aplikasi React anda lebih mantap dan mesra pengguna. Dengan sokongan untuk jenis kompleks seperti objek, cangkuk ini ialah alat yang berkuasa untuk mengurus keadaan yang perlu berterusan merentasi muat semula halaman atau dikongsi melalui URL.
Anda boleh melanjutkan cangkuk ini lagi untuk mengendalikan struktur data yang lebih kompleks, tetapi untuk kebanyakan kes penggunaan, pelaksanaan ini akan meliputi keperluan anda.
( Sila komen pada artikel tersebut supaya saya boleh membuat ini lebih baik dan memperbaiki sebarang kesilapan yang mungkin saya lakukan, terima kasih terlebih dahulu. )
Jangan ragu untuk mengikuti saya di platform lain juga
Github
Atas ialah kandungan terperinci Cangkuk React Tersuai untuk menyegerakkan keadaan dengan URL. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!