reactjs - NextJS: לדחוף ערך חדש של מחרוזת שאילתה ל-asPath קיים או לעדכן את מחרוזת השאילתה הקיימת


אני קצת אבוד לגבי איך מערכת הנתיבים של NextJS עובדת:

יש לי מאמרים לפי קטגוריות שיכולות להיות:

Medical
Charity
Wedding
Funeral

יש לי סרגל ניווט שבו המשתמש יכול להציג מאמרים לפי קטגוריה, ויכול גם לחפש לפי מילות מפתח. תכונת הקטגוריה פועלת בצורה מושלמת.

זוהי הדרך שבה תפריט הניווט שלי נראה:

זה אומר שאם המשתמש ילחץ על All, אנחנו מציגים את כל המאמרים:

הנה התרחיש:

  • כאשר אנו לוחצים לדוגמה על Medical, ה-URL נראה כך: http://localhost:3000/articles?category=medical
  • כאשר אנו לוחצים על all, כתובת ה-URL נראית כמו http://localhost:3000/articles
  • כאשר אנו לוחצים על all ומחפשים את מילת המפתח COVID, כתובת ה-URL נראית כך: http://localhost:3000/articles?search=covid

בעיה

כעת אני רוצה לשלב קטגוריות וחיפוש: אם המשתמש לוחץ על medical ומבצע חיפוש עבור המילה COVID, כתובת ה-URL חייבת להיראות כך: http://localhost:3000/articles?category=medical&search=covid.

לאחר קבלת תוצאת החיפוש, כאשר המשתמש משנה את מילת המפתח, אני רוצה להחליף את מחרוזת השאילתא search עם הערך החדש.

איך ניסיתי לעשות?

אני יודע שלאובייקט הנתיב של NextJS יש:

  • pathname: הנתיב הנוכחי. כלומר הנתיב של הדף בתוך /pages
  • ו-asPath: הנתיב בפועל (כולל השאילתה) המוצג בדפדפן
const { push, asPath } = useRouter();

const onSearchKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
    const keyword = e.currentTarget.value;
    if (e.key === "Enter") {
      url = !isEmpty(keyword.trim())
        ? {
          pathname: asPath,
          query: { search: keyword },
        }
        : {
          pathname,
        };
      push(url);
    }
  };

אבל לעשות זאת הוא הצפנת ה-asPath וכתוצאה מכך לכתובת זו: http://localhost:3000/article%3Fcategory=covid&search=covid שמציגה את דף ה-404 לא נמצא.

אז, אני אפילו לא יודע אם אני יכול להחליף את search בערך חדש כשהמשתמש רוצה לבצע חיפוש חדש.

תשובה #1

פתרתי את הבעיה על ידי אי שימוש ב-asPath: במקום זאת השתמשתי ב-pathname יחד עם אופרטור הפריסה באופן הבא:

url = !isEmpty(keyword.trim())
     ? {
        pathname,
        query: { ...query, search: keyword },
     }: {
        pathname: page,
     };