
التعامل مع Search Params باستخدام nuqs في Next.js App Router
M. Zakyuddin Munziri
@zakiego
كتب أصلاً بـ Bahasa Indonesia.
الملخص
nuqs هي مكتبة لإدارة حالة search params لـ Next.js.
السلوك الافتراضي لـ nuqs هو أولوية العميل (client-first)، مما يعني أنه عند تحديث search params، لن تتم إعادة عرض صفحة الويب. هذا أمر رائع إذا كانت قيمة search params تحتاج فقط للقراءة من جانب العميل.
ومع ذلك، إذا كانت القيمة بحاجة للقراءة من قبل الخادم، فلن يتم اكتشاف التغييرات. لتفعيل إعادة العرض حتى يتمكن الخادم من قراءة التغييرات، تحتاج إلى إضافة الخيار { shallow: false }.
هذا يختلف عن next-query-params التي تتبنى نهج أولوية الخادم (server-first)، مما يعني أن كل تغيير في القيمة يُقرأ فوراً من قبل الخادم.
جرّب الفرق بين search params من جانب العميل وجانب الخادم في
nuqsعلى nuqs-playground.vercel.appبالنسبة لـ
next-query-params، يمكنك تجربتها على seach-params-playground.vercel.app
المقدمة
هذا المقال هو استمرار لـ إنشاء مكون البحث في Next.js App Router. سابقاً، استخدمنا مكتبة next-query-params لإدارة search params. هذه المرة سنتعامل مع nuqs.
في الواقع، جربت nuqs من قبل. لكن بسبب المعرفة المحدودة، لم أستمر في استخدامها.
شكراً لـ @alfonsusac الذي حفزني لقراءة توثيق nuqs بشكل أعمق.
نظرة عامة
nuqs تعرّف نفسها بأنها "مدير حالة search params آمن النوع لـ Next.js".
لنبدأ. بالطبع، الإطار المستخدم في هذا المقال هو Next.js.
أولاً، قم بتثبيت nuqs.
pnpm add nuqsأنشئ ملف مكون يحتوي على <input/>، ثم أعد توجيه قيمة onChange إلى search params باستخدام useQueryState.
// src/app/client.tsx
'use client'
import { useQueryState } from 'nuqs'
export function Demo() {
const [name, setName] = useQueryState("name");
return (
<>
<input value={name || ""} onChange={(e) => setName(e.target.value)} />
<p>Hello, {name}!</p>
</>
);
}لماذا نحتاج لكتابة "use client" في أعلى السطر؟
لأنه منذ تقديم نموذج App Router في Next.js، كل مكون هو مكون خادم بشكل افتراضي. ومع ذلك، في هذه الحالة، نحتاج إلى
onChangeمن<input/>وهو مكون عميل. لذلك، نحتاج لكتابة "use client" في السطر الأعلى لإخبار React أن هذا مكون عميل (Client Components).
أخيراً، استورد مكون <Demo/> الذي أنشأناه إلى /src/app/hello/page.tsx.
النتيجة هي أنه في كل مرة تدخل قيمة في <input/>، سيتم تحديث search params فوراً.
على سبيل المثال، example.com/hello ستتغير إلى example.com/hello?name=zaki.
لمزيد من الأمثلة، تحقق من nuqs.47ng.com/playground.
الفرق بين nuqs و next-query-params
سابقاً، استخدمت nuqs في هذه التغريدة. الفرق الأكثر وضوحاً بين nuqs و next-query-params هو:
nuqsتعمل على أولوية العميل- بينما
next-query-paramsهي أولوية الخادم
ما الفرق؟
يمكنك تجربة الفرق مباشرة بين أولوية العميل (nuqs-playground.vercel.app/nuqs-client) وأولوية الخادم (nuqs-playground.vercel.app/nuqs-server)
مع كون nuqs أولوية العميل، لا يمكننا الوصول إلى search params من جانب الخادم.
على سبيل المثال، نزور الصفحة example.com/hello.
ثم، عند كتابة اسم في الإدخال، يتغير الرابط إلى example.com/hello?name=zaki.
على الرغم من تغيّر الرابط، لأن nuqs هي أولوية العميل، ستظل قيمة name التي نحصل عليها من search params فارغة، إذا استخدمنا جانب الخادم.
nuqs بشكل افتراضي لا تفعّل تحديث الصفحة للخادم. لذا حتى لو تغيّر الرابط في متصفحنا إلى example.com/hello?name=zaki، يظل الخادم يعتبرنا في صفحة example.com/hello فقط.
interface Props {
searchParams: {
name?: string;
};
}
export default async function Page(props: Props) {
const { searchParams } = props;
const { name } = searchParams;
return (
<div>
value from server: {name}
</div>
);
}ومع ذلك، الأمر مختلف في مكونات العميل، مثل <Demo/> السابق.
دعني أضع الكود مرة أخرى.
// src/app/client.tsx
'use client'
import { useQueryState } from 'nuqs'
export function Demo() {
const [name, setName] = useQueryState("name");
return (
<>
<input value={name || ""} onChange={(e) => setName(e.target.value)} />
<p>Hello, {name}!</p>
</>
);
}في هذا الكود، سيتم قراءة قيمة name فوراً، حتى لو لم نقم بتحديث الصفحة للخادم.
هذا عكس next-query-params، حيث في كل مرة تقوم بتحديث القيمة في <input/>، سيتم تفعيل تحديث الصفحة.
نتيجة لذلك، عندما يتحدث الرابط من example.com/hello إلى example.com/hello?name=zaki، يتعرف الخادم فوراً على أننا موجودون بالفعل في الرابط example.com/hello?name=zaki.
nuqs لكن من جانب الخادم
بعد القراءة بعناية أكبر، على الرغم من أن nuqs هي أولوية العميل، لا يزال بإمكاننا تشغيل إعادة العرض بإضافة { shallow: false }.
التوثيق nuqs.47ng.com/docs/options
useQueryState("foo", { shallow: false });مع الإعداد أعلاه، يمكننا الحصول على search params من خلال جانب الخادم.
يمكنك تجربتها هنا nuqs-playground.vercel.app/nuqs-server.
هدية
إليك بعض الردود من مؤلف nuqs مباشرة:
أيضاً، اتضح أن nuqs تُستخدم من قبل vercel.com أيضاً
الخاتمة
nuqs لديها تجربة مطور (DX) أفضل مقارنة بـ next-query-params، لأنك لا تحتاج لإضافة كود لميزة التخطيط.
ومع ذلك، لأن nuqs هي أولوية العميل، لا يمكن الحصول على تغييرات قيمة search params مباشرة من جانب الخادم، إلا باستخدام { shallow: false }. هذا يختلف عن next-query-params التي هي أولوية الخادم من البداية، لذا يمكن قراءة تغييرات القيمة من قبل الخادم فوراً.
في النهاية، كل شيء يعود للمطور. الأسئلة هي:
- هل تقوم بالجلب من جانب الخادم أم جانب العميل؟
- بعد ذلك، هل تحتاج قيمة search params لتكون قابلة للقراءة من قبل الخادم؟ لأن في بعض الحالات، لا يجب أن تكون search params قابلة للقراءة فوراً من قبل الخادم
هذا كل شيء، شكراً لكم.
انتهت الكتابة يوم الخميس، 11 أبريل 2024 الساعة 13:39، اليوم الثاني من العيد.


