支持在 route hoc 中渲染 react router 的 props

support render props of react router in route hoc

我正在为 public 路由和私有路由编写 HOC。如果路由是私有的并且用户已通过身份验证,则让 him/her 进入该页面,否则重定向到登录组件。如果路由是 public 并且用户未通过身份验证,则显示该页面,如果用户未通过身份验证但用户已通过身份验证并且仍然转到登录页面,则显示登录页面,然后将用户重定向到根页面。这工作正常。但是如果我使用渲染而不是组件,那么它就不起作用。只有当我从名为 react-router 组件的 props 传递组件时,我才能让它工作。

如果用户用户渲染道具,我怎样才能让它工作?

这是我的代码

<Switch>
  <PrivateRoute
    exact
    path="/"
    render={() => <Home name="something" />} {/* this does not work */}
  />
  <PrivateRoute exact path="/demo" component={Demo} />
  <PublicRoute restricted={true} path="/auth" component={Authentication} />
</Switch>

PublicRoute.js

const PublicRoute = ({component: Component, restricted, ...rest}) => {
  return (
    <Route
      {...rest}
      render={props =>
        isLogin() && restricted ? <Redirect to="/" /> : <Component {...props} />
      }
    />
  )
}

PrivateRoute.js

const PrivateRoute = ({component: Component, ...rest}) => {
  return (
    <Route
      {...rest}
      render={props =>
        isLogin() ? <Component {...props} /> : <Redirect to="/auth/login" />
      }
    />
  )
}

此外,如果还有其他需要改进的地方,请提出建议。

问题是在您的自定义路线中,您总是使用 component 道具。因此,当传递 render 道具时,它会被您自定义路由中的道具否决,因此会尝试呈现提供的 component.

当你像下面的函数一样修改它时,它就会起作用。它还提取 render 道具,如果它是一个函数,它将使用它而不是 component 道具。

const PrivateRoute = ({component: Component, render, ...rest}) => {
    const renderContent = props => {
        if (!fakeAuth.isAuthenticated) {
            return (
                <Redirect
                    to={{
                        pathname: "/login",
                        state: { from: props.location }
                    }}
                />
            )
        }
        return (typeof render === 'function') ? render(props) : <Component {...props} />
    }

    return (
        <Route {...rest} render={renderContent} />
    );
}