【问题标题】:How to watch if the querystring changes within React Router v6?如何查看 React Router v6 中的查询字符串是否发生变化?
【发布时间】:2021-01-10 22:44:35
【问题描述】:

我有一个带有下拉列表的表单,当我选择下拉列表时,我将值推送到查询字符串上。当第一次点击带有该查询字符串的 url 时,它将查询字符串参数存储到状态中,然后使用它来填充下拉列表。这一切都按预期工作。我的问题是触发表单以在同一页面上查看查询字符串的更改。

如果我已经在页面上但是然后单击反应路由器链接到同一页面但使用不同的查询字符串参数它不会捕获/看到它已更改。我想知道如何观察查询字符串的变化,或者是否有更好的方法来处理这个问题。

我发现您可以收听 React-Router 打算在后台使用的历史对象,但我在这方面收效甚微,而且我不确定这是否是正确的方法https://github.com/ReactTraining/history/blob/master/docs/getting-started.md

我尝试将以下内容添加到页面,但是当我更改 url 的查询字符串(也称为搜索)时,侦听器似乎永远不会触发。想知道我错过了什么吗?

  useEffect(() => {
    // Listen for changes to the current location.
    console.info("wiring up history listener");
    let unlisten = history.listen(({ location, action }) => {
      console.info("HISTORY CHANGED", location.search);
      console.log(action, location.pathname, location.state);
      // Plan was to update my state here if needed
    });

    return unlisten;
  }, []);

使用react-router-dom v6。

【问题讨论】:

  • 你将一个空的依赖数组传递给useEffect,所以它只会在第一次渲染时运行。此外,useEffect 的返回是一个回调,将在触发重新渲染时在卸载之前运行。
  • 根据您的需要寻找useHistoryuseParamsuseLocationThey already exist,不用自己动手

标签: javascript reactjs react-router react-router-dom


【解决方案1】:

如果您想监听路径查询字符串参数的更改,您需要“监听”来自location 对象的更改。使用useLocation 钩子获取location 对象。

location

{
  key: 'ac3df4', // not with HashHistory!
  pathname: '/somewhere',
  search: '?some=search-string',
  hash: '#howdy',
  state: {
    [userDefined]: true
  }
}

使用效果挂钩监听变化。

const { search } = useLocation();

useEffect(() => {
  // search query string changed
}, [search]);

【讨论】:

  • 这看起来像我需要的!谢谢今天会玩,然后回复你:)
  • @PeteDuncanson 拍摄,刚刚注意到你用 react-router(-dom) 的版本 6 标记了你的问题,确实有一个额外的 useSearchParams react 钩子(超过v4/v5),marzelin 指出(尽管他们对 history 对象的解释不太准确)。我知道使用位置对象会起作用,而且我看不出为什么使用 useSearchParams 也不起作用。
【解决方案2】:

您的代码不起作用,因为react-router 使用了不同的history 实例,因此当通过react-routerLink 进行更改时,您的自定义侦听器不会被触发(它由不同的history 的版本)。但是,单击浏览器的前进或后退按钮应该会触发您的侦听器,因为这会通知所有 history 实例。

最适合您用例的工具是useSearchParams hook

const [searchParams] = useSearchParams();

useEffect(() => {
  // code for handling search query change
}, [searchParams]);

此外,您可能不需要使用useEffect,而是将searchParams 视为搜索数据的真实来源,而无需在该州创建另一个实体。

【讨论】:

  • 使用查询作为事实的来源是要走的路,也是我遗漏的一点。我确实必须将查询字符串存储在状态中(作为一个完整的字符串),这样我就可以将它与当前的进行比较,这样如果它们不同,我就可以触发重新获取我的数据。宾果游戏!
【解决方案3】:

react-router 带有您需要的所有hooks。听起来像你想要的:useParams

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-11
  • 2022-11-10
  • 2018-02-17
  • 2017-06-20
  • 1970-01-01
  • 2015-12-16
  • 2019-07-05
相关资源
最近更新 更多