عند إنشاء تطبيقات React، غالبًا ما يكون من المفيد عكس الحالة في عنوان URL. وهذا لا يجعل الحالة قابلة للمشاركة فحسب، بل يسمح أيضًا للمستخدمين بوضع إشارة مرجعية على الصفحات أو تحديثها دون فقدان سياقها. في هذه المقالة، سنقوم بإنشاء خطاف React مخصص يسمى useParamState في TypeScript. سيعمل هذا الخطاف مثل useState، ولكنه سيقوم أيضًا بمزامنة الحالة مع معلمات البحث في عنوان URL. والأهم من ذلك أنه سيدعم قيم الكائنات المعقدة.
يعد خطاف useSearchParams الخاص بجهاز React Router ممتازًا لإدارة معلمات بحث URL، لكن مزامنتها مع حالة المكون قد تكون مرهقة. يعالج الخطاف useParamState هذا الأمر من خلال:
( هذا يفترض أنك تعرف بالفعل كيفية إعداد مشروع رد فعل، إذا لم تقم بالتوجه إلى Vite)
تأكد من تثبيت React-router-dom:
npm install react-router-dom
إليك كيفية تنفيذ الخطاف 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( key: string, defaultValue: T ): [T, (newValue: Partial | T) => void] { const [searchParams, setSearchParams] = useSearchParams(); const paramValue = searchParams.get(key); const [state, setState] = useState (() => { if (paramValue === null) { return defaultValue; } try { return JSON.parse(paramValue) as T; } catch { return paramValue as T; } }); const setParamState = useCallback( (newValue: Partial | 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;
يبدأ الخطاف بالتحقق من وجود معلمة البحث المحددة في عنوان URL. إذا حدث ذلك، فسيقوم الخطاف بتوزيعه واستخدامه كحالة أولية. وإلا فإنه سيعود إلى القيمة الافتراضية المقدمة.
تقوم وظيفة setParamState بتحديث كل من الحالة الداخلية ومعلمة البحث في عنوان URL. يستخدم JSON.stringify لإجراء تسلسل للحالة، مما يسمح لنا بتخزين الكائنات المعقدة في عنوان URL.
يدعم الخطاف أنواعًا مختلفة (سلسلة، رقم، منطقي، وكائن) من خلال الاستفادة من جينات TypeScript وتحليل JSON.
دعونا نرى كيف يمكنك استخدام useParamState في مكون React:
import React from 'react'; import useParamState from './useParamState'; interface FilterState { status: string; sortBy: string; } const MyComponent: React.FC = () => { const [filter, setFilter] = useParamState('filter', { status: 'all', sortBy: 'date', }); return ( ); }; export default MyComponent;Current Filter: {filter.status}, Sort by: {filter.sortBy}
للتأكد من أن الخطاف useParamState يعمل كما هو متوقع، يمكنك كتابة اختبارات الوحدة باستخدام @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 }) => ({children} ); const { result } = renderHook(() => useParamState('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' }); });
يعمل خطاف useParamState على تبسيط عملية مزامنة الحالة مع معلمات بحث URL، مما يجعل تطبيقات React الخاصة بك أكثر قوة وسهولة في الاستخدام. مع دعم الأنواع المعقدة مثل الكائنات، يعد هذا الخطاف أداة قوية لإدارة الحالة التي تحتاج إلى الاستمرار عبر عمليات إعادة تحميل الصفحة أو مشاركتها عبر عناوين URL.
يمكنك توسيع هذا الخطاف للتعامل مع هياكل البيانات الأكثر تعقيدًا، ولكن بالنسبة لمعظم حالات الاستخدام، سيغطي هذا التنفيذ احتياجاتك.
( قم بالتعليق على المقالة حتى أتمكن من تحسين هذا الأمر وتحسين أي أخطاء ربما ارتكبتها، شكرًا مقدمًا. )
لا تتردد في متابعتي على منصات أخرى أيضًا
لينكد إن
جيثب
إنستجرام
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3