首页 > 解决方案 > 将自定义道具传递给私有路由 - React Typescript

问题描述

我们有一个 React 组件XYZ,它具有某些 UI,需要根据已安装组件的路由隐藏/显示。

例如,如果路线是/show -> 如果路线是/hide-> 它应该显示一个表格,如果路线是/hide-> 它应该隐藏表格。

正在使用 react-router-dom,但不想在 history.push(...) 中使用状态。

我正在寻找一种可以在定义路由时实现的解决方案,以便以后使用此路由的任何开发人员都不必担心维护状态。

PS:我们在 TS 中使用 Private Route,除非使用,否则无法覆盖 render 方法any

interface PrivateRouteProps extends RouteProps {
}

const PrivateRoute: FunctionComponent<PrivateRouteProps> = ({
    component: Component,
    ...rest
  }) => {
    if (!Component) return null;    
    return (
        <Route
            {...rest}
            render={(props) => true
                ? <Component {...props}/>  // looking for a way to pass custom props here
                : <Redirect to={{ pathname: '/', state: { from: props.location } }} />}
        />
    )
}

用法 :

<PrivateRoute path='/show' component={XYZ} />

关于如何在此 PrivateRoute 中传递道具然后将其传递给组件的任何帮助将不胜感激。TIA

标签: javascriptreactjstypescriptreact-routerreact-router-dom

解决方案


道具

我假设额外的道具是已知的并且可以作为道具传递给PrivateRoute组件。

我们将 定义type PrivateRouteProps为一个泛型,它取决于 的类型ExtraProps。它将额外传递的道具作为道具名称的对象extraProps

我们将接受除 之外的PrivateRouteProps所有正常值,因为我们想用我们自己的定义覆盖它。我们的版本是典型的,也是我们的(作为顶级道具)。RoutePropscomponentcomponentRouteComponentPropsExtraProps

type PrivateRouteProps<ExtraProps> = Omit<RouteProps, 'component'> & {
  component: ComponentType<RouteComponentProps & ExtraProps>
  extraProps: ExtraProps;
}

零件

在我们的render函数中,我们可以通过检查 的值来实现show/切换,该值已经提供了.hideprops.match.pathRouteComponentProps

当我们调用 时,我们将提供给 的所有道具以及我们Component传入的所有道具都传递下去。我们根本不需要覆盖的定义,我们只是在给定的基础上添加我们自己的额外道具。如果我们不这样做,我们会收到错误,因为我们输入了它期望接收的内容。renderextraPropsPrivateComponentrenderComponentExtraProps

我们是通用的,因此我们将键入 props PrivateRoute,而不是将组件本身键入为 。FunctionComponent

const PrivateRoute = <ExtraProps extends {}>({
    component: Component,
    extraProps,
    ...rest
  }: PrivateRouteProps<ExtraProps>) => {
    if (!Component) return null;
    return (
        <Route
            {...rest}
            render={(props) => props.match.path.startsWith('/show')
                ? <Component {...extraProps} {...props}/>
                : <Redirect to={{ pathname: '/', state: { from: props.location } }} />}
        />
    )
}

用法

现在,当我们声明 a 时PrivateRoute,我们必须始终传递适当的额外道具。

const RenderNumber = ({n}: {n: number}) => (
  <div>{n}</div>
)

<PrivateRoute path="/show/something" component={RenderNumber} extraProps={{n: 5}}/>
// renders the number 5

打字稿游乐场链接


推荐阅读