Обход блокировщика обновлений в компоненте без маршрута с помощью 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} />
Другие вопросы по тегам