成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

在 Next.js 中使用 URL 參數(shù)進(jìn)行狀態(tài)管理

開發(fā) 前端
URL 查詢參數(shù)是一個(gè)強(qiáng)大的工具,可以顯著提升網(wǎng)站性能并豐富用戶體驗(yàn)。令人欣慰的是,越來(lái)越多的開發(fā)者在構(gòu)建實(shí)際應(yīng)用時(shí)將查詢參數(shù)整合到他們的代碼庫(kù)中。
在 React.js 和 Next.js 等前端框架中,useState 是管理應(yīng)用狀態(tài)的首選方案。然而,隨著應(yīng)用規(guī)模的擴(kuò)大,開發(fā)者們需要更高級(jí)的狀態(tài)管理方案來(lái)提升用戶體驗(yàn)、SEO 和優(yōu)化效果。URL 參數(shù)就是一個(gè)很有吸引力的替代方案!

雖然 useState hook 仍然是 React 開發(fā)者在函數(shù)組件中管理狀態(tài)的寵兒,但它也有其局限性。特別是當(dāng)應(yīng)用規(guī)模擴(kuò)大、更多組件需要數(shù)據(jù)時(shí),我們經(jīng)常需要在組件間傳遞數(shù)據(jù)(這種做法被親切地稱為** props 鉆取**),或者求助于狀態(tài)管理庫(kù)。以下是一些值得思考的限制:

  • 局部組件作用域: useState 的設(shè)計(jì)目的是處理特定組件內(nèi)的狀態(tài)。如果你需要在不同組件之間共享狀態(tài)或處理全局狀態(tài),可以考慮使用 React 的 useContext hook 或采用 Redux-toolkit 等強(qiáng)大的狀態(tài)管理工具 。
  • SEO 優(yōu)化不足: 當(dāng) URL 參數(shù)未能反映 useState 促成的狀態(tài)調(diào)整時(shí),可能會(huì)影響 SEO 效果 。
  • 用戶體驗(yàn)考慮: 在電商應(yīng)用中,如果不使用 URL 參數(shù)可能導(dǎo)致用戶體驗(yàn)欠佳,因?yàn)橛脩魺o(wú)法輕松地與他人分享他們的偏好設(shè)置。
  • Props 鉆取: 如果你依賴 useState 來(lái)管理全局狀態(tài),你會(huì)發(fā)現(xiàn)自己需要將狀態(tài)和其設(shè)置函數(shù)作為 props 傳遞給每個(gè)需要的組件。

要克服這些限制,你可以考慮使用其他狀態(tài)管理方案,如 useReducer hook、useContext hook,或者 Redux 和 MobX 等第三方解決方案。

為什么選擇 URL 參數(shù)而不是 useState?

URL 參數(shù)(使用問(wèn)號(hào)(?)附加在 URL 末尾的查詢字符串)具有多種功能,例如通過(guò)搜索和分頁(yè)等功能增強(qiáng)網(wǎng)頁(yè)功能、提升頁(yè)面 SEO,并經(jīng)常用于跟蹤營(yíng)銷活動(dòng)。一個(gè) URL 可以包含多個(gè)參數(shù),用 & 符號(hào)分隔。

那么為什么要使用 URL 參數(shù)而不是 useState?

URL 參數(shù)在某些場(chǎng)景下可以勝過(guò) useState,特別是當(dāng)目標(biāo)是以更靈活和可共享的方式管理應(yīng)用狀態(tài)時(shí)。以下是幾個(gè)選擇 URL 參數(shù)的令人信服的理由:

  • 網(wǎng)頁(yè)書簽功能: URL 參數(shù)使你能夠直接將狀態(tài)信息編碼到 URL 中,簡(jiǎn)化了用戶為特定頁(yè)面添加書簽并與他人分享的過(guò)程。
  • 增強(qiáng)的狀態(tài)管理: 在具有搜索功能的網(wǎng)頁(yè)中,通過(guò) URL 參數(shù)保存搜索詞可以確保即使用戶刷新瀏覽器后也能保留。
  • 簡(jiǎn)化組件邏輯: URL 參數(shù)提供了簡(jiǎn)化單個(gè)組件內(nèi)部邏輯的途徑。相比于依賴 useState 實(shí)現(xiàn)復(fù)雜的搜索功能,你可以讓 URL 查詢參數(shù)承擔(dān)這個(gè)任務(wù)。

雖然 useState 在管理局部組件狀態(tài)方面很強(qiáng)大,但將其與 URL 參數(shù)結(jié)合使用可以提供更健壯的狀態(tài)管理方法。

理解 URL 參數(shù)查詢模式

URL 參數(shù)由鍵值對(duì)組成,便于靈活的數(shù)據(jù)傳輸。鍵作為標(biāo)識(shí)符,而值與之綁定,兩者用等號(hào)(=)分隔。一個(gè) URL 中可以包含多個(gè)參數(shù),每個(gè)參數(shù)用 & 符號(hào)分隔。

例如:

https://www.example.com/search?q=mens+t-shirt&size=3xl&color=white&sort=asc

這個(gè) URL 表示一個(gè)搜索路由,搜索詞由鍵"q"指定。后續(xù)的參數(shù)如"size"、"color"和"sort"定義了額外的搜索條件,每個(gè)參數(shù)都在提升用戶的瀏覽體驗(yàn)。

常見的 URL 參數(shù)用例

網(wǎng)站經(jīng)常利用 URL 參數(shù)來(lái)處理高級(jí)狀態(tài),提升營(yíng)銷活動(dòng)效果和頁(yè)面 SEO。使用 URL 參數(shù)有很多好處:

  • 排序和篩選: URL 參數(shù)使用戶能夠?qū)W(wǎng)頁(yè)內(nèi)容進(jìn)行排序和篩選,定制他們的瀏覽體驗(yàn)。例如:https://www.example.com/dresses?sort=a-z
  • 搜索查詢: 參數(shù)可以封裝用戶的搜索查詢,便于將來(lái)參考。例如:https://www.example.com/search?q=t-shirt
  • 語(yǔ)言翻譯: URL 參數(shù)可以處理語(yǔ)言翻譯查詢,讓用戶以他們偏好的語(yǔ)言訪問(wèn)網(wǎng)頁(yè)。例如:https://www.example.com/news?lang=fr
  • 跟蹤營(yíng)銷活動(dòng): 參數(shù)可以包含營(yíng)銷活動(dòng)查詢,幫助跟蹤點(diǎn)擊率和活動(dòng)效果。例如:https://www.example.com/home?utm_campaign=fbid_newyearpromo&referrer_id=25jh8s
  • 頁(yè)面分頁(yè): URL 參數(shù)在網(wǎng)頁(yè)搜索結(jié)果分頁(yè)中發(fā)揮重要作用,確保導(dǎo)航流暢。例如:https://www.example.com/blog/articles?page=3

URL 參數(shù)是增強(qiáng)網(wǎng)頁(yè)功能和提升各種在線平臺(tái)用戶體驗(yàn)的有力工具。

使用 URL 進(jìn)行全局狀態(tài)管理的優(yōu)缺點(diǎn)

在管理 Web 應(yīng)用狀態(tài)時(shí),利用 URL 可以帶來(lái)諸多好處。它可以提升用戶體驗(yàn),便于跟蹤營(yíng)銷活動(dòng),并增強(qiáng)頁(yè)面 SEO。但如果使用不當(dāng),也會(huì)給網(wǎng)頁(yè)帶來(lái)挑戰(zhàn)。以下是一些需要考慮的優(yōu)缺點(diǎn):

優(yōu)點(diǎn)

  • 可添加書簽和分享的 URL: 用戶可以為應(yīng)用的特定 URL 狀態(tài)添加書簽或與他人分享,提升可用性和協(xié)作性。
  • 深度鏈接: 開發(fā)者可以使用 URL 參數(shù)創(chuàng)建與查詢字符串匹配的動(dòng)態(tài)頁(yè)面,改善應(yīng)用狀態(tài)的深度鏈接。
  • 服務(wù)器端渲染(SSR)兼容性: 使用 Next.js 進(jìn)行需要服務(wù)器端渲染的項(xiàng)目是理想的選擇,因?yàn)?URL 參數(shù)可以在服務(wù)器和客戶端之間傳輸狀態(tài)數(shù)據(jù)。

缺點(diǎn)

  • 安全隱患: 存儲(chǔ)在 URL 參數(shù)中的敏感信息可能帶來(lái)重大安全風(fēng)險(xiǎn),因?yàn)樗鼈儗?duì)用戶可見且可能被篡改。
  • 重復(fù)內(nèi)容: URL 參數(shù)使用不當(dāng)可能導(dǎo)致多個(gè)令人困惑的 URL,并可能降低 SEO 引擎的頁(yè)面排名。
  • 復(fù)雜的 URL 結(jié)構(gòu): 復(fù)雜的查詢參數(shù)往往會(huì)導(dǎo)致冗長(zhǎng)、難以閱讀的 URL,使用戶不愿點(diǎn)擊和信任你的鏈接,從而減少頁(yè)面訪問(wèn)量。

在 Next.js 中實(shí)現(xiàn) URL 參數(shù)

創(chuàng)建組件

創(chuàng)建兩個(gè)組件。首先,創(chuàng)建一個(gè)處理將搜索和排序查詢附加到 URL 的搜索輸入組件。

import { useRouter, useSearchParams } from "next/navigation";

首先,我們從 next/navigation 導(dǎo)入查詢 hooks。useRouter hook 使我們能夠在客戶端應(yīng)用中導(dǎo)航到任何路由。另一方面,useSearchParams hook 允許我們操作 URL 中的查詢,如 get、set 和 delete 方法。

const SearchSortInput = () => {
  const router = useRouter();
  const searchParams = useSearchParams();
  const query = searchParams?.get("q");
  const sort = searchParams?.get("sort");

  const newParams = URLSearchParams(searchParams.toString());
};

接下來(lái),我們初始化 hooks,并使用搜索參數(shù)從 URL 中檢索現(xiàn)有查詢。這允許我們?cè)谳斎胱侄沃斜3秩魏尾樵儭?/p>

return (
  <div className="flex items-center space-x-4 mb-4">
    <button
      onClick={() => router.push("/")}
      className="border border-gray-300 p-2 rounded text-black border-black"
    >
      Home
    </button>

    <form
      className="
        flex items-center space-x-4 mb-4 mx-auto
      "
    >
      <input
        type="text"
        placeholder="Search..."
        name="search"
        key={query || ""}
        defaultValue={query || ""}
        className="border border-gray-300 p-2 rounded text-black border-black"
      />
      <button
        type="submit"
        className="border border-gray-300 p-2 rounded text-black border-black"
      >
        Search
      </button>
      <div className="flex gap-2 items-center">
        <p>Sort by:</p>

        <select
          defaultValue={sort || "default"}
          name="sort"
          onChange={(e) => {
            newParams.set("sort", e.target.value);
            router.push(`/search?${newParams.toString()}`);
          }}
          className="border border-gray-300 p-2 rounded"
        >
          <option value="default">Default</option>
          <option value="title">Name</option>
          <option value="asc">Ascending</option>
          <option value="desc">Descending</option>
          <option value="a-z">A to Z</option>
        </select>
      </div>
    </form>
  </div>
);

在這一部分中,我們創(chuàng)建了輸入字段供用戶輸入搜索查詢。我們沒(méi)有使用 useState 來(lái)處理輸入的更新,而是將輸入的 defaultValue 設(shè)置為我們現(xiàn)有的查詢。這樣,即使用戶離開頁(yè)面或刷新頁(yè)面,他們的查詢?nèi)匀粫?huì)存在。這是使用 URL 查詢參數(shù)的好處之一。

const handleSubmit = (event) => {
  event.preventDefault();
  const val = event.target;
  const search = val.search;
  const sortBy = val.sort;

  if (search.value) {
    newParams.set("q", search.value);
  } else {
    newParams.delete("q");
  }
  if (sortBy.value) {
    newParams.set("sort", sortBy.value);
  } else {
    newParams.delete("sort");
  }
  router.push(`/search?${newParams.toString()}`);
};

這個(gè)函數(shù)負(fù)責(zé)處理查詢邏輯。我們不使用 useState 來(lái)管理輸入,而是從表單中獲取值。如果搜索輸入有值,我們用鍵"q"和用戶輸入的值創(chuàng)建新查詢。如果搜索輸入為空,我們刪除查詢。排序也遵循相同的過(guò)程。最后,我們導(dǎo)航到 /search 路由并將查詢添加到 URL。

return (
  <div className="flex items-center space-x-4 mb-4">
    // 其他代碼...
    <form onSubmit={handleSubmit}>
    // 輸入字段...
    </form>
  </div>
);

export default SearchSortInput;

要完成這個(gè)組件的邏輯,我們將 handleSubmit 函數(shù)綁定到表單并導(dǎo)出組件。

創(chuàng)建數(shù)據(jù)顯示組件

首先,我們創(chuàng)建一個(gè)接受 data、q 和 sort 參數(shù)的函數(shù)。我們?cè)陧敳堪?nbsp;use client 以表明這是一個(gè) Next.js 客戶端組件。

const filteredData = () => {
  let newData = [...data];

  if (q) {
    newData = newData.filter(
      (item) =>
        item.name.toLowerCase().includes(q.toLowerCase()) ||
        item.username.toLowerCase().includes(q.toLowerCase()),
    );
  }

  if (sort) {
    newData.sort((a, b) => {
      if (sort === "name") {
        return a.name.localeCompare(b.name);
      } else if (sort === "a-z") {
        return b.username.localeCompare(a.username);
      } else if (sort === "asc") {
        return a.id - b.id;
      } else if (sort === "desc") {
        return b.id - a.id;
      } else {
        return 0;
      }
    });
  }

  return newData;
};

然后我們創(chuàng)建一個(gè) filteredData 函數(shù),它使用 JavaScript 內(nèi)置的 filter 和 sort 方法來(lái)搜索和排序數(shù)據(jù)。如果沒(méi)有搜索或排序查詢,我們只返回完整數(shù)據(jù)。

return (
  <div className="flex flex-col items-center">
    <h1
      className="
        text-4xl font-semibold text-center mb-4 mt-8 mx-auto 
      "
    >
      My Feed
    </h1>
    <ul className="grid grid-cols-4 mx-auto max-w-[1260px] gap-10"></ul>
    {filteredData().map((item) => (
      <ul
        key={item.id}
        className="flex border border-gray-300 p-4 rounded w-[600px] mb-4 gap-4"
      >
        <h3 className="text-lg font-semibold mb-2">{item.name}</h3>
        <p className="text-gray-500">Username: {item.username}</p>
        <p className="text-gray-500">Email: {item.email}</p>
      </ul>
    ))}
  </div>
);

最后,我們遍歷過(guò)濾后的數(shù)據(jù)并渲染它。

創(chuàng)建搜索頁(yè)面

這是根據(jù)用戶查詢顯示搜索結(jié)果的頁(yè)面。我們使用之前創(chuàng)建的 DisplayData 組件。打開 search 文件夾中的 page.js 文件并粘貼以下代碼片段。

"use client";
import { useSearchParams } from "next/navigation";
import { Suspense, useEffect, useState } from "react";
import DisplayData from "../_components/DisplayData";
import SearchSortInput from "../_components/SearchInput";

export default function Search() {
  const searchParams = useSearchParams();
  const q = searchParams.get("q");
  const sort = searchParams.get("sort");
  const [data, setData] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      const searchParams = new URLSearchParams();

      if (q) {
        searchParams.append("q", q);
      }

      if (sort) {
        searchParams.append("sort", sort);
      }
      const response = await fetch(`/api/users`);
      const data = await response.json();

      setData(data);
    };

    fetchData();
  }, [q, sort]);

  return (
    <div className="m-12">
      <SearchSortInput />
      {q && (
        <h3 className="text-2xl font-bold mb-4">搜索結(jié)果: {q}</h3>
      )}
      {sort && <p className="text-[14px] mb-4">排序方式: {sort}</p>}
      <Suspense fallback={<div>加載中...</div>} key={q}>
        <DisplayData data={data} sort={sort} q={q} />
      </Suspense>
    </div>
  );
}

最后,要完成我們的 URL 查詢?cè)?Next.js 中的實(shí)現(xiàn)。打開 App 文件夾中的 page.js 文件并粘貼以下代碼片段。

"use client";
import { Suspense, useEffect, useState } from "react";
import DisplayData from "./_components/DisplayData";
import SearchSortInput from "./_components/SearchInput";

export default function Home() {
  const [data, setData] = useState([]);
  const fetchPosts = async () => {
    const res = await fetch("/api/users");
    const data = await res.json();
    setData(data);
  };

  useEffect(() => {
    fetchPosts();
  }, []);
  return (
    <div className="m-12">
      <SearchSortInput />
      <Suspense fallback={<div>加載中...</div>}>
        <DisplayData data={data} />
      </Suspense>
    </div>
  );
}

在這個(gè)文件中,我們的主要任務(wù)是從 API 路由獲取數(shù)據(jù)。作為首頁(yè),我們顯示搜索輸入和 DisplayData 組件。我們只在這里渲染組件,而搜索和排序邏輯則在專門用于此目的的 /search 頁(yè)面上實(shí)現(xiàn)。

總結(jié)

URL 查詢參數(shù)是一個(gè)強(qiáng)大的工具,可以顯著提升網(wǎng)站性能并豐富用戶體驗(yàn)。令人欣慰的是,越來(lái)越多的開發(fā)者在構(gòu)建實(shí)際應(yīng)用時(shí)將查詢參數(shù)整合到他們的代碼庫(kù)中。

責(zé)任編輯:姜華 來(lái)源: 大遷世界
相關(guān)推薦

2021-06-01 08:20:47

源碼狀態(tài)管理

2024-12-13 08:37:32

2025-02-03 00:00:35

2023-10-06 23:40:49

Spring開發(fā)

2025-03-06 00:00:00

2020-12-14 11:40:27

Next.js SSRReact

2024-12-16 08:40:51

2024-03-29 08:32:01

Node.jsNext.js組件

2024-09-04 10:27:53

2024-04-28 10:56:34

Next.jsWeb應(yīng)用搜索引擎優(yōu)化

2023-10-27 15:13:12

Next.jsRust

2025-03-17 03:00:00

2024-04-03 13:27:28

Next.js擴(kuò)展項(xiàng)目

2022-02-22 20:48:48

RemixNext.js框架

2023-09-04 08:20:00

2025-01-17 09:29:42

2021-11-26 10:29:24

jsRemix開源

2025-02-05 07:00:00

Next.jsWeb前端

2023-09-20 10:14:03

Next.js前端

2024-03-04 07:33:39

RemixReact框架
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 一区二区中文 | 国产xxx在线观看 | 午夜欧美一区二区三区在线播放 | 亚洲成人精品在线观看 | 日韩一区二区三区在线观看视频 | 亚洲一区二区三区福利 | 亚洲精品视频在线观看免费 | 在线观看av网站永久 | 亚洲a一区 | 欧亚av在线 | 亚洲一区二区三区四区五区中文 | 国产精品日韩欧美一区二区三区 | 91在线一区| 国产美女精品视频 | 亚洲国产精品精华素 | 欧美精品一二区 | 精品1区| 欧美精品综合在线 | 国产精品美女久久久av超清 | 在线成人| 做a视频 | 精品国产一区二区国模嫣然 | 一级毛片视频在线观看 | 国产午夜精品一区二区三区 | 九九九久久国产免费 | 中文字幕一级毛片视频 | 国产.com| 欧美在线二区 | 99精品免费久久久久久久久日本 | 欧美一级久久精品 | 国产真实精品久久二三区 | 亚洲欧美国产一区二区三区 | 欧美日韩一区二区在线观看 | 成人在线中文字幕 | 精品久久久久久久久久久下田 | 成人av在线播放 | 国产精品久久久久久久久免费桃花 | 日本国产高清 | 欧美成人精品一区二区男人看 | 青青久久 | 欧美一区二区三区视频 |