带有 URL 的 useState:如何使用 useSearchParams 保持状态

  • Post author:
  • Post category:其他


反应 useStateHook 是在 React 组件的上下文中保持状态的好方法。 这篇文章演示了一个简单的 React Hook,它将状态存储在 URL 查询字符串中,构建在 React Router 之上 useSearchParams钩。

  • useState

  • 有状态的 URL

  • 这 useSearchParams钩

  • 这 useSearchParamsState钩

  • 在您的网站上保留查询字符串

useState

的使用 useState钩子 看起来像这样:

const [greeting, setGreeting] = useState('hello world');
​
// ....
​
setTotal('hello John'); // will set greeting to 'hello John'

但是使用有一个缺点 useState; 该状态不是持久的,也不是可共享的。 因此,如果您希望其他人看到您在应用程序中可以看到的内容,您依赖于他们执行使您的应用程序进入当前状态的相同操作。

这样做既费时又容易出错,所以如果有一种简单的方法来共享状态不是很好吗?

有状态的 URL

在用户之间共享状态而不需要持久性后端的一种有效方法是使用 URL。 URL 可以包含路由和查询字符串/搜索参数形式的所需状态。 搜索参数特别强大,因为它们完全通用且可自定义。

非常感谢 URLSearchParamsAPI ,可以在不往返服务器的情况下操作查询字符串。 这是我们可以构建的原语; 只要 URL 限制(大约2,000 个字符),我们就可以自由地将状态保留在 URL 中。 不超过

考虑:


Our Apps

上面的 URL 存储了一个状态: greeting.

现在考虑:


超过 20 万开发人员使用 LogRocket 来创造更好的数字体验 了解更多 →



Our Apps

上面的 URL 更进一步并存储了多个状态: greeting和 name.

这 useSearchParams钩

如果您正在使用 React, React Router 会直接在 URL 中使用状态,特别是查询字符串或搜索参数的形式。 它通过 useSearchParams钩:

import { useSearchParams } from "react-router-dom";
​
const [searchParams, setSearchParams] = useSearchParams();
​
const greeting = searchParams.get('greeting');
​
// ...
​
setSearchParams({ 'greeting': 'bonjour' }); // will set URL like so https://our-app.com?greeting=bonjour - this value will feed through to anything driven by the URL

这是一种很好的机制,可以在本地和以可共享的方式持久化状态。

这种方法的一个显着好处是它不需要发布到服务器。 它只是使用浏览器 API,例如 URLSearchParamsAPI。 更改查询字符串参数完全在本地和即时发生。

这 useSearchParamsState钩

什么 useSearchParamsHook 不做的是维护其他查询字符串或搜索参数。

如果您在应用程序中维护多个状态,这可能意味着多个查询字符串或搜索参数。 那么,非常有用的是一个 Hook,它允许我们在不丢失其他状态的情况下更新状态。

此外,如果我们不必先获得 searchParams对象,然后对其进行操作。 是我们的时候了 useSearchParamsState钩:

import { useSearchParams } from "react-router-dom";
​
export function useSearchParamsState(
    searchParamName: string,
    defaultValue: string
): readonly [
    searchParamsState: string,
    setSearchParamsState: (newState: string) => void
] {
    const [searchParams, setSearchParams] = useSearchParams();
​
    const acquiredSearchParam = searchParams.get(searchParamName);
    const searchParamsState = acquiredSearchParam ?? defaultValue;
​
    const setSearchParamsState = (newState: string) => {
        const next = Object.assign(
            {},
            [...searchParams.entries()].reduce(
                (o, [key, value]) => ({ ...o, [key]: value }),
                {}
            ),
            { [searchParamName]: newState }
        );
        setSearchParams(next);
    };
    return [searchParamsState, setSearchParamsState];
}

The above Hook can roughly be thought of as useState<string>, but storing that state in the URL.

Let’s think about how it works. When initialized, the Hook takes two parameters:

  • searchParamName:这是状态被持久化的查询字符串参数的名称

  • defaultValue:如果查询字符串中没有值,这是备用值

然后钩子继续包裹 useSearchParams钩。 它审问 searchParams对于提供的 searchParamName,如果它不存在,则回退到 defaultValue.

这 setSearchParamsState方法定义看起来有些复杂,但实际上它所做的只是获取现有搜索参数的内容并为当前属性应用新状态。

可能值得在这里暂停一下,以观察潜伏在此实现中的观点:对于同一个搜索参数具有多个值实际上是有效的。 虽然这是可能的,但很少使用它。 此实现仅允许任何给定参数的单个值,因为这是非常有用的行为。

有了这一切,我们就有了一个可以像这样使用的钩子:

const [greeting, setGreeting] = useSearchParamsState("greeting", "hello");

上面的代码返回一个 greeting值,它来自于 greeting搜索参数。 它还返回一个 setGreeting函数,它允许我们设置 greeting价值。 这是相同的 API useState,所以对于 React 用户来说应该是惯用的。 巨大的!

在您的站点中保留查询字符串

现在,我们设置了这个令人兴奋的机制,它允许我们在 URL 中存储状态,因此,通过向某人发送 URL 来轻松共享状态。

还有一种有用的方法是在我们的站点中导航而不会丢失该状态。 想象一下,我选择了一个日期范围并将其存储在我的 URL 中。 当我从一个屏幕点击到另一个屏幕时,我想坚持这一点——我不想在每个屏幕上重新选择日期范围。

我们应该怎么做? 好吧,事实证明这很容易。 我们需要的只是 useLocation钩子和对应的 location.search财产。 那代表查询字符串,所以每次我们渲染一个链接时,我们只是像这样包含它:

const [location] = useLocation();
​
return (<Link to={`/my-page${location.search}`}>Page</>)

现在,当我们浏览我们的站点时,该状态将保持不变。




Yoco百度文库下载软件,自动识别快速下载,有一款堪比冰点神器!



结论

在这篇文章中,我们创建了一个 useSearchParamsStateHook,它允许将状态持久化到 URL 以用于共享目的。

全面了解生产 React 应用程序

调试 React 应用程序可能很困难,尤其是当用户遇到难以重现的问题时。 如果您对监控和跟踪 Redux 状态、自动显示 JavaScript 错误以及跟踪缓慢的网络请求和组件加载时间感兴趣,请 尝试 LogRocket 。

LogRocket 就像一个用于 Web 和移动应用程序的 DVR,几乎可以记录您的 React 应用程序上发生的所有事情。 无需猜测问题发生的原因,您可以汇总并报告问题发生时应用程序所处的状态。 LogRocket 还监控您的应用程序的性能,并使用客户端 CPU 负载、客户端内存使用情况等指标进行报告。

LogRocket Redux 中间件包为您的用户会话增加了一层额外的可见性。 LogRocket 记录来自 Redux 存储的所有操作和状态。


来自 LogRocket 的更多精彩文章:

  • 不要错过 The Replay 来自 LogRocket 的精选时事通讯

  • 了解 LogRocket 的 Galileo 如何消除噪音以主动解决应用程序中的问题

  • 使用 React 的 useEffect 优化应用程序的性能

  • 之间切换 在多个 Node 版本

  • 了解如何 使用 AnimXYZ 为您的 React 应用程序制作动画

  • 探索 Tauri ,一个用于构建二进制文件的新框架

  • 比较 NestJS 与 Express.js



版权声明:本文为weixin_47967031原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。