使用 React Router 和 React Hooks 绕过非路由组件中的更新阻止程序
Bypassing update blocker in non-route component with React Router and React Hooks
我将 React Router 与通用页面组件一起使用,该组件基于 slug 从 WP Rest API 获取内容。我可以直接通过 url 访问页面,并且路由有效。
我的 Footer 组件中有一个小菜单,它使用 React Router <Link>
组件链接到使用 Page 组件的各个页面。
当我单击这些链接时,url 正在更新,但页面组件没有使用更新后的 slug 重新呈现,因此没有抓取正确的页面内容。
这绝对是更新阻塞,如 React Router 文档中所述:https://reacttraining.com/react-router/web/guides/dealing-with-update-blocking
这涵盖了大多数解决方案,但在我的例子中,Footer 组件不是 Route,而是 Layout 组件的子组件,Layout 组件也是无路由的,并包装了所有其他组件。
要修复,文档建议我需要将 React Router location
prop 发送到组件树下。
我已经尝试使用 withRouter
导出所有组件到组件树下,应该传递这个属性,但它不起作用。
如何在单击 <Footer>
组件中的 <Link>
时让 <Page>
组件更新?
App.js中的路线:
<BrowserRouter>
<Layout
addToCart={addToCart}
removeFromCart={removeFromCart}
clearCart={clearCart}
cart={cart}
catalog={catalog}
>
<Switch>
<Route exact path="/" render={() => <Home catalog={catalog} />} />
<Route
exact
path="/catalog"
render={() => (
<Catalog addToCart={addToCart} catalog={catalog} />
)}
/>
<Route path="/:slug" render={props => <Page {...props} />} />
<Route
path="/catalog/:category/:slug"
render={() => (
<SingleProduct addToCart={addToCart} catalog={catalog} />
)}
/>
</Switch>
</Layout>
</BrowserRouter>
Layout.js(简体):
<Layout>
<Header />
{children}
<Footer />
<Layout
<Footer />
中的链接:
<ul className="nostyle footer-links">
<li>
<Link to="/faq">FAQ</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/contact">Contact Us</Link>
</li>
</ul>
//...
export default withRouter(Footer)
Page.js:
const Page = props => {
const slug = props.match.params.slug
const [page, setPage] = useState()
const fetchPage = async () => {
const result = await axios(
`${params.liveUrl}${params.pages}?slug=${slug}`
)
setPage(result.data)
}
useEffect(() => {
fetchPage()
}, [])
return (
<Fragment>
<div className="page" key={page[0].slug}>
{page[0].content}
</div>
</Fragment>
)
}
export default withRouter(Page)
因此,如果我直接访问 /faq
或 /about
,它会按照路由中的指示加载 <Page />
组件,传入 slug 并正确显示所有内容。
但是,如果我单击 <Footer />
中的一个链接,url 会发生变化,但 <Page />
组件不会刷新为新的 slug,因此不会刷新正确的页面数据。如果我重新加载页面,则会加载正确的数据。
如何在更改路由时强制 <Page>
组件更新?
请注意,我使用的是 React hooks 而不是 Redux。
谢谢!
您需要为页面组件设置唯一键,这样每次键更改时都会呈现该组件的新实例。
假设您的 slug 是独一无二的,您可以执行以下操作:
<Page key={props.match.params.slug} {...props} />
或者,您也可以这样做:
<Page key={window.location.pathname} {...props} />
我将 React Router 与通用页面组件一起使用,该组件基于 slug 从 WP Rest API 获取内容。我可以直接通过 url 访问页面,并且路由有效。
我的 Footer 组件中有一个小菜单,它使用 React Router <Link>
组件链接到使用 Page 组件的各个页面。
当我单击这些链接时,url 正在更新,但页面组件没有使用更新后的 slug 重新呈现,因此没有抓取正确的页面内容。
这绝对是更新阻塞,如 React Router 文档中所述:https://reacttraining.com/react-router/web/guides/dealing-with-update-blocking
这涵盖了大多数解决方案,但在我的例子中,Footer 组件不是 Route,而是 Layout 组件的子组件,Layout 组件也是无路由的,并包装了所有其他组件。
要修复,文档建议我需要将 React Router location
prop 发送到组件树下。
我已经尝试使用 withRouter
导出所有组件到组件树下,应该传递这个属性,但它不起作用。
如何在单击 <Footer>
组件中的 <Link>
时让 <Page>
组件更新?
App.js中的路线:
<BrowserRouter>
<Layout
addToCart={addToCart}
removeFromCart={removeFromCart}
clearCart={clearCart}
cart={cart}
catalog={catalog}
>
<Switch>
<Route exact path="/" render={() => <Home catalog={catalog} />} />
<Route
exact
path="/catalog"
render={() => (
<Catalog addToCart={addToCart} catalog={catalog} />
)}
/>
<Route path="/:slug" render={props => <Page {...props} />} />
<Route
path="/catalog/:category/:slug"
render={() => (
<SingleProduct addToCart={addToCart} catalog={catalog} />
)}
/>
</Switch>
</Layout>
</BrowserRouter>
Layout.js(简体):
<Layout>
<Header />
{children}
<Footer />
<Layout
<Footer />
中的链接:
<ul className="nostyle footer-links">
<li>
<Link to="/faq">FAQ</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/contact">Contact Us</Link>
</li>
</ul>
//...
export default withRouter(Footer)
Page.js:
const Page = props => {
const slug = props.match.params.slug
const [page, setPage] = useState()
const fetchPage = async () => {
const result = await axios(
`${params.liveUrl}${params.pages}?slug=${slug}`
)
setPage(result.data)
}
useEffect(() => {
fetchPage()
}, [])
return (
<Fragment>
<div className="page" key={page[0].slug}>
{page[0].content}
</div>
</Fragment>
)
}
export default withRouter(Page)
因此,如果我直接访问 /faq
或 /about
,它会按照路由中的指示加载 <Page />
组件,传入 slug 并正确显示所有内容。
但是,如果我单击 <Footer />
中的一个链接,url 会发生变化,但 <Page />
组件不会刷新为新的 slug,因此不会刷新正确的页面数据。如果我重新加载页面,则会加载正确的数据。
如何在更改路由时强制 <Page>
组件更新?
请注意,我使用的是 React hooks 而不是 Redux。
谢谢!
您需要为页面组件设置唯一键,这样每次键更改时都会呈现该组件的新实例。
假设您的 slug 是独一无二的,您可以执行以下操作:
<Page key={props.match.params.slug} {...props} />
或者,您也可以这样做:
<Page key={window.location.pathname} {...props} />