如何从 URL 获取状态,并且在 Next.JS 中状态发生变化时更新查询参数?

问题描述 投票:0回答:3

初学者,但发现这很棘手。因此,我们将不胜感激!

我想让用户过滤一些选项。这些过滤器应该反映在 URL 中。例如:

http://localhost:3000/items?counter=1

现在,当用户访问

http://localhost:3000/items?counter=2
时,我希望将其反映在状态中并将其放入状态中。如果同一用户以某种方式更改状态,我希望将其反映在 url 中。我确实知道如何做这两件事。

但我觉得我在这里陷入了无限循环:

    useEffect(() => {
        router.push(`/items?counter=${counter}`, undefined, { shallow: true })
    }, [counter])

    useEffect(() => {
        setCounter(parseInt(router.query.counter))
    }, [router.query.counter])

我如何才能最好地从查询参数中获取状态,同时在每次状态更改时始终浅层更新查询参数?

reactjs url react-hooks next.js url-parameters
3个回答
6
投票

始终只更新其中一个,并通过监听第一个的变化来更新另一个。由于状态始终源自查询,因此我会通过

useEffect
更新状态,并始终直接更改查询。

这意味着您不直接更新状态。每当你想要更新状态时,你都需要更新查询:

const updateCounterQuery = currentCounter => router.push(`/items?counter=${currentCounter}`, undefined, { shallow: true })

useEffect(() => {
  setCounter(parseInt(router.query.counter))
}, [router.query.counter])

但是,为什么在这种情况下还需要一个状态呢?始终使用从查询中获得的值:

const updateCounterQuery = counter => router.push(`/items?counter=${counter }`, undefined, { shallow: true })

const counter = +router.query.counter

5
投票

对于需要多个查询字符串(例如

?counter=2&filter=true
)或同时更新(例如
?latitude=47.367&longitude=8.543
)的更复杂的用例,将逻辑抽象为钩子通常是有意义的。

next-usequerystate这样的库正好解决了这个用例。 thisthis 等指南和示例是自定义开发的良好切入点。


0
投票

更容易使用库来字符串化/解析参数,我创建了一个 https://github.com/asmyshlyaev177/state-in-url

如果不小心,

useEffect
可能会形成循环。像这样应该可以解决问题:

  const { state, updateState, updateUrl } = useUrlState(form);

  const timer = React.useRef(0 as unknown as NodeJS.Timeout);
  React.useEffect(() => {
    clearTimeout(timer.current);
    timer.current = setTimeout(() => {
      // using JSON.stringify internally to compare state and do router.push only if values are different
      updateUrl(state);
    }, 500);

    return () => {
      clearTimeout(timer.current);
    };
  }, [state, updateUrl]);
© www.soinside.com 2019 - 2024. All rights reserved.