我正在使用React / Next构建一个无头的电子商务站点,并且有一个[product].js
动态路由,该路由用于生成所有产品页面,并使用getStaticPaths()
和getStaticProps()
生成页面很好。
我正在useState
中使用[product].js
钩子来管理数字输入(用于数量)和其他一些事情。
加载的第一个产品页面工作正常,但是当我转到其他产品页面时,它们使用第一个产品的相同状态。
有没有办法使状态在两次路由更改之间不持久?
通过一些挖掘,我发现这是next的问题,并且在他们的积压中。它实质上是由于该组件没有密钥这一事实而产生的。这意味着在同一动态路由上的路由之间切换不能正确注册,并导致组件使用陈旧状态。
我发现的可能解决方案是:
export async function getStaticProps({params}) {
const props = await getData(params);
// key is needed here
props.key = data.id;
return {
props: props
}
}
这是我的实现方式,不适用于我:
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
}
}
我尝试将内容包装在另一个组件中,并为其添加一个键,就像这样,但是它仅适用于被包装的组件中包含的状态。
return(
<OuterComponent key={props.id}>
// components within here, that have their own state, now work
</OuterComponent>
)
答案 0 :(得分:1)
您可以在动态路由器上使用 useEffect
hook 和 useRoute
r hook 来重置状态。
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 (
......
)
}
答案 1 :(得分:0)
您似乎遇到了与我发现的问题相同的问题: https://github.com/vercel/next.js/issues/9992
从我阅读的内容来看,要解决此问题,您需要做的就是更改getStaticProps
以返回具有唯一键的对象:
export async function getStaticProps({ params }) {
const slug = params.product
const props = await client.query({
query: singleProductQuery,
variables: { id: slug }
});
return {
props: props,
key: slug
}
}
您之前所做的是将密钥传递给props对象而不是getStaticProps
的root返回对象
答案 2 :(得分:0)
您可以使用useEffect挂钩重置状态
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(
...
)
}
因此,当您的道具发生变化时-您的状态就会更新。