在 react-router 中通过 hook 访问 staticContext

Access staticContext through hook in react-router

我想创建一个通用 "not-found" 组件,如果使用 StaticRouter,它会将 statusCode 设置为 404。我知道我可以做到:

<Route
  render={(routeComponentProps) => <NotFound {...routeComponentProps} />}
/>

或者使用文档描述的子函数,但随着我的应用程序越来越复杂,我想将它简化为我指定所有其他路由的方式,以避免必须记住传递道具到 NotFound 组件。像这样:

<Route>
  <NotFound />
</Route> 

这意味着我想使用钩子(最好)访问 <NotFound/> 内部的 staticContext,但不幸的是,目前这似乎不可能,因为 useRouteMatch 钩子可以不是 return staticContext.

我目前的解决方法是从 react-router 内部抓取 __RouterContext 并将其传递给 useContext 挂钩,但这看起来很老套,可能不受支持。但是它在服务器端和客户端都可以正常工作(使用正常的BrowserRouter

import React, { useContext } from "react"
import { __RouterContext } from "react-router"

export const NotFound: React.FC = () => {
    const { staticContext } = useContext(__RouterContext)
    if (staticContext) {
        staticContext.statusCode = 404
    }

    return (
        <div>
            <h3>404: Not found</h3>
        </div>
    )
}

export default NotFound

是否有我可以使用的挂钩,或者可能计划在 useRouteMatch 挂钩中开始支持它?

我认为您不能使用已记录的挂钩在内部访问 staticContext。如果存在未记录的钩子,那么它不会是比您当前的 __RouterContext 技巧(我发现它已经很优雅)更好的解决方法。

不过,如果您放宽对“钩子”的要求,您可以做些事情。这可能没问题:挂钩非常适合重用逻辑,但不需要用于解决所有问题。

您可以在 <NotFound /> 中访问 staticContext 而无需任何道具:您只需要添加一个新的 catch-all <Route /> inside.

export const NotFound: React.FC = () => {
  return (
    <Route
      render={({ staticContext }) => {
        if (staticContext) {
          staticContext.statusCode = 404
        }

        return (
          <div>
            <h3>404: Not found</h3>
          </div>
        )
      }}
    >
  )
}

...

<Route>
  <NotFound />
</Route>