javascript - 使用 React Router 和 React Hooks 绕过非路由组件中的更新阻止程序

标签 javascript reactjs react-router react-router-v4 react-hooks

我将 React Router 与通用页面组件一起使用,该组件基于 slug 从 WP Rest API 获取内容。我可以通过 url 和路由直接访问页面。

我的 Footer 组件中有一个使用 React Router 的小菜单 <Link>使用页面组件链接到各种页面的组件。

当我单击这些链接时,url 正在更新,但页面组件并未使用更新后的 slug 重新呈现,因此无法获取正确的页面内容。

这绝对是更新阻塞,如 React Router 文档中所述:https://reacttraining.com/react-router/web/guides/dealing-with-update-blocking

这涵盖了大多数解决方案,但在我的例子中,Footer 组件不是 Route,而是 Layout 组件的子组件,Layout 组件也是无路由的,并包装了所有其他组件。

要修复,文档建议我需要发送 React Router location向下支撑组件树。

我尝试使用 withRouter 导出所有组件沿着应该传递这个 Prop 的组件树向下移动,但它不起作用。

我怎样才能得到 <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)

页面.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} />

关于javascript - 使用 React Router 和 React Hooks 绕过非路由组件中的更新阻止程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54098143/

相关文章:

javascript - date-fns 中的什么方法相当于 moment().toISOString()

javascript - Jquery中的事件需要多次点击

javascript - 使用Reactjs Router Switch进行导航时如何在网页之间传递变量

reactjs - Ionic/React/TypeScript,react-router 导航动画触发两次

javascript - 完全获取数据后加载状态变化

javascript - 如何延迟 NavLink 的 react ?

javascript - 如何使文本在 html/javascript 中闪烁?

javascript - var evt = (evt) 是什么意思?事件 : ((event) ? 事件 : null);?

javascript - 为什么我的 React 组件不渲染 HTML,但日志正确?

node.js - 错误: onSubmit doesn't work on reactjs jsx render method