Обход блокировщика обновлений в компоненте без маршрута с помощью React Router и React Hooks - PullRequest
0 голосов
/ 08 января 2019

Я использую 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 Ответ

0 голосов
/ 16 января 2019

Вам необходимо установить уникальный ключ для вашего компонента Page, поэтому новый экземпляр этого компонента будет отображаться каждый раз, когда ключ изменяется.

Предполагая, что ваш слаг уникален, вы можете сделать следующее:

<Page key={props.match.params.slug} {...props} />

Кроме того, вы также можете сделать это так:

<Page key={window.location.pathname} {...props} />
...