简体   繁体   English

将自定义道具传递给私有路由 - React Typescript

[英]Pass custom Props to Private Route - React Typescript

We have a React component XYZ that has certain UI that needs to be hidden/showed based on the route that has mounted the component.我们有一个 React 组件XYZ ,它具有某些 UI,需要根据已安装组件的路由隐藏/显示。

For eg, if the route is /show -> it shall show a table if the route is /hide-> it shall hide the table.例如,如果路线是/show -> 如果路线是/hide-> 它应该显示一个表格,如果路线是/hide-> 它应该隐藏表格。

react-router-dom is being used, but would not like to use state in history.push(...).正在使用 react-router-dom,但不想在 history.push(...) 中使用 state。

Am looking for a solution that can be achieved while defining the routes so that any developer who used this route later don't have to worry about maintaining the state.我正在寻找一种在定义路线时可以实现的解决方案,这样以后使用此路线的任何开发人员都不必担心维护 state。

PS: We are using Private Route with TS, and overriding the render method is not possible unless any is used. PS:我们在 TS 中使用 Private Route,除非使用any方法,否则无法覆盖 render 方法。

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 } }} />}
        />
    )
}

usage:用法:

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

Any help on how can I pass props in this PrivateRoute and then pass it on to the Component will be appreciated.TIA关于如何在此 PrivateRoute 中传递道具然后将其传递给组件的任何帮助将不胜感激。TIA

Props道具

I am assuming that that the extra props are known and can be passed as props to the PrivateRoute component.我假设额外的道具是已知的并且可以作为道具传递给PrivateRoute组件。

We will define the type PrivateRouteProps as a generic which depends on the type of ExtraProps .我们将type PrivateRouteProps定义为泛型,这取决于ExtraProps的类型。 It will take the additional passed-down props as an object with the prop name extraProps .它将附加传递的道具作为 object 使用道具名称extraProps

Our PrivateRouteProps will accept all of the normal RouteProps except for component , because we want to override that with our own definition.我们的PrivateRouteProps将接受除了component之外的所有普通RouteProps ,因为我们想用我们自己的定义覆盖它。 Our version of the component is one which takes the typical RouteComponentProps and also our ExtraProps (as top-level props).我们的component版本采用典型的RouteComponentPropsExtraProps (作为顶级道具)。

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

Component零件

In our render function, we can implement the show / hide toggling by checking the value of props.match.path , which is already provided a part of RouteComponentProps .在我们的render function 中,我们可以通过检查 props.match.path 的值来实现show / hide切换,该值RouteComponentProps props.match.path提供。

When we call the Component , we pass down all of the props which were provided to the render and also all of the extraProps that we passed in to PrivateComponent .当我们调用Component时,我们将提供给render器的所有 props 以及我们传入的所有extraProps传递给PrivateComponent We are not having to overwrite the definition of render at all, we're just adding our own extra props on top of what's given.我们根本不需要重写render的定义,我们只是在给定的基础上添加我们自己的额外道具。 If we didn't, we would get errors because we typed the Component such that it expects to receive ExtraProps .如果我们不这样做,我们会收到错误,因为我们键入了Component ,因此它期望接收ExtraProps

Our PrivateRoute is generic, so instead of typing the component itself as FunctionComponent , we will type the props.我们的PrivateRoute是通用的,因此我们不会将组件本身键入为FunctionComponent ,而是键入 props。

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 } }} />}
        />
    )
}

Usage用法

Now when we declare a PrivateRoute , we must always pass the appropriate extra props.现在,当我们声明PrivateRoute时,我们必须始终传递适当的额外道具。

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

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

Typescript Playground Link Typescript 游乐场链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM