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

ant*_*elm 6 url url-parameters reactjs next.js react-hooks

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

我想让用户过滤一些选项。这些过滤器应该反映在 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])
Run Code Online (Sandbox Code Playgroud)

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

Ori*_*ori 5

始终只更新其中一个,并通过监听第一个的更改来更新另一个。由于状态始终源自查询,因此我将通过 更新状态useEffect,并始终直接更改查询。

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

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

useEffect(() => {
  setCounter(parseInt(router.query.counter))
}, [router.query.counter])
Run Code Online (Sandbox Code Playgroud)

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

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

const counter = +router.query.counter
Run Code Online (Sandbox Code Playgroud)


swi*_*mer 5

对于需要多个查询字符串(例如?counter=2&filter=true)或同时更新(例如?latitude=47.367&longitude=8.543)的更复杂的用例,将逻辑抽象为挂钩通常是有意义的。

像next-usequerystate 这样的库正好解决了这个用例。像这样的指南和示例定制开发的良好切入点。