通过 react-router 中的钩子访问 staticContext

Tho*_*mas 9 reactjs react-router server-side-rendering

我想创建一个通用的“未找到”组件,如果StaticRouter使用它,将 statusCode 设置为 404 。我知道我可以这样做:

<Route
  render={(routeComponentProps) => <NotFound {...routeComponentProps} />}
/>
Run Code Online (Sandbox Code Playgroud)

Or use a child function as the doc describes, but as my app is growing in complexity I'd like to simplify it down to the way I specify all my other routes in order to avoid having to remember to pass props to the NotFound component. Something like this:

<Route>
  <NotFound />
</Route> 
Run Code Online (Sandbox Code Playgroud)

This means I'd like to access staticContext inside <NotFound/> using a hook (preferrably), but unfortunately that does not seem possible at this time as the useRouteMatch hook does not return staticContext.

My current workaround is to grab __RouterContext from inside react-router and pass it to a useContext hook, but this seems hacky and is probably not supported. However it does work fine both server-side and client side (using the normal 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
Run Code Online (Sandbox Code Playgroud)

Is there a hook I can use or perhaps plans to start supporting this within the useRouteMatch hook?

小智 4

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

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

您可以在没有任何道具的情况下访问staticContext内部<NotFound />:您只需<Route /> 在内部添加一个 newcatch-all 。

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> 
Run Code Online (Sandbox Code Playgroud)