[英]How to NOT persist state between Next.js dynamic routes?
I'm building a headless eCommerce site using React/Next and have a [product].js
dynamic route which is used to generate all product pages, using getStaticPaths()
and getStaticProps()
which generates the pages fine.我正在使用 React/Next 构建一个无头电子商务网站,并有一个[product].js
动态路由,用于生成所有产品页面,使用getStaticPaths()
和getStaticProps()
可以很好地生成页面。
I'm using useState
hook within [product].js
to manage a number input (for quantity) and a couple of other things.我在[product].js
中使用useState
挂钩来管理数字输入(用于数量)和其他一些事情。
The first product page loaded works fine, but when I go to other product pages, they use the same state from the first product.加载的第一个产品页面工作正常,但是当我 go 到其他产品页面时,他们使用与第一个产品相同的 state。
Is there a way to have the state NOT persist between route changes?有没有办法让 state 在路线更改之间不存在?
Through some digging, I found that this is an issue with next and is in their backlog.通过一些挖掘,我发现这是 next 的问题,并且在他们的积压中。 It essentially stems from the fact that the component doesn't have a key.它本质上源于组件没有密钥的事实。 This means switching between routes on the same dynamic route doesn't register correctly and causes the component to use stale state.这意味着在同一动态路由上的路由之间切换不会正确注册并导致组件使用陈旧的 state。
A possible solution I found was this:我发现的一个可能的解决方案是:
export async function getStaticProps({params}) {
const props = await getData(params);
// key is needed here
props.key = data.id;
return {
props: props
}
}
This is my implementation which doesn't work for me:这是我的实现,对我不起作用:
export default function ProductPage(props) {
// this state doesn't reset between dynaic route changes
const [quantity, setQuantity] = useState(1)
return(
...
)
}
export async function getStaticProps({ params }) {
const slug = params.product
const props = await client.query({
query: singleProductQuery,
variables: { id: slug }
})
props.key = props.data.product.slug
return {
props: props
}
}
I tried wrapping the contents within another component and adding a key to that, like so, but it only works for the state contained within components that are wrapped.我尝试将内容包装在另一个组件中并为其添加一个密钥,就像这样,但它仅适用于包含在包装的组件中的 state。
return(
<OuterComponent key={props.id}>
// components within here, that have their own state, now work
</OuterComponent>
)
It seems that you've encountered the same issue thread that I've found: https://github.com/vercel/next.js/issues/9992您似乎遇到了与我发现的相同的问题线程: https://github.com/vercel/next.js/issues/9992
It seems from what I've read that to fix your case, all you need to do is change your getStaticProps
to return an object with a unique key:从我读到的内容看来,要解决您的问题,您需要做的就是更改您的getStaticProps
以返回具有唯一键的 object :
export async function getStaticProps({ params }) {
const slug = params.product
const props = await client.query({
query: singleProductQuery,
variables: { id: slug }
});
return {
props: props,
key: slug
}
}
What you've been doing previously is passing a key to the props object instead of root return object for getStaticProps
您之前所做的是将密钥传递给道具 object 而不是 root 返回 object 以获得getStaticProps
You can use useEffect hook to reset state您可以使用 useEffect 挂钩重置 state
export default function ProductPage(props) {
// this state doesn't reset between dynaic route changes
const [quantity, setQuantity] = useState(1)
useEffect(() => {
setQuantity(props.quantity) // <-- this props comes from getStaticProps
}, [props]) // <--- useEffect will keep tracking changing props
return(
...
)
}
So when your props changes - your state updates.因此,当您的道具发生变化时 - 您的 state 会更新。
You can use useEffect
hook and useRoute
r hook at dynamic router to reset the state.您可以在动态路由器上使用useEffect
hook 和useRoute
r hook 来重置 state。
import {useState, useEffect} from 'react'
import {useRouter} from 'next/router'
const ProductPage = (props) => {
const [state, setState] = useState(someState)
const dynamicRoute = useRouter().asPath
useEffect(() => {
setState(resetState) // When the dynamic route change reset the state
}, [dynamicRoute])
//Some other logic
return (
......
)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.