Обход блокировщика обновлений в компоненте без маршрута с помощью React Router и React Hooks
Я использую React Router со стандартным компонентом Page, который извлекает контент из WP Rest API на основе слага. Я могу посетить страницы напрямую через URL и маршрутизацию работ.
У меня есть небольшое меню в моем компоненте нижнего колонтитула, который использует React Router <Link>
компонент, связывающий различные страницы с использованием компонента Page.
Когда я нажимаю на эти ссылки, URL обновляется, но компонент Page не выполняет повторную визуализацию с обновленным фрагментом и, следовательно, не получает правильное содержимое страницы.
Это определенно обновление блокировки, как описано в документации по React Router здесь: https://reacttraining.com/react-router/web/guides/dealing-with-update-blocking
Это охватывает большинство решений, однако в моем случае компонент нижнего колонтитула не является маршрутом и является дочерним компонентом компонента макета, который также не содержит маршрутов и охватывает все другие компоненты.
Для исправления, документы предполагают, что мне нужно будет отправить React Router location
опустите дерево компонентов.
Я попытался экспортировать все компоненты, используя withRouter
вниз по дереву компонентов, которое должно пропустить эту опору, но она не работает.
Как я могу получить <Page>
компонент для обновления, когда я нажимаю на <Link>
в <Footer>
составная часть?
Маршруты в 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 />
Компонент, как указано в маршруте, передавая в слаг и все отображается правильно.
Но, если я нажму одну из ссылок в <Footer />
, URL меняется, но <Page />
компонент не обновляется с новым слагом и, следовательно, с правильными данными страницы. Если я перезагрузить страницу, загружаются правильные данные.
Как я могу заставить <Page>
компонент для обновления при изменении маршрута?
Обратите внимание, что я использую React-хуки, а не Redux.
Спасибо!
1 ответ
Вам необходимо настроить уникальный ключ для вашего компонента Page, поэтому новый экземпляр этого компонента будет отображаться при каждом изменении ключа.
Предполагая, что ваш слаг уникален, вы можете сделать следующее:
<Page key={props.match.params.slug} {...props} />
Кроме того, вы также можете сделать это так:
<Page key={window.location.pathname} {...props} />