reactjs - Implementere react-router PrivateRoute i Typescript-prosjekt
Her er et eksempel fra react-router på hvordan man legger til en komponent for beskyttede ruter:
function PrivateRoute({ component: Component, ...rest }) {
return (
<Route
{...rest}
render={props =>
fakeAuth.isAuthenticated ? (
<Component {...props} />
) : (
<Redirect
to={{
pathname: "/login",
state: { from: props.location }
}}
/>
)
}
/>
);
}
https://reacttraining.com/react-router/web/example/auth-workflow
Jeg har prøvd å implementere denne funksjonaliteten i mitt Typescript-prosjekt, ved å bruke eksemplet ovenfor som inspirasjon.
komponenter/Ruter
import PrivateRoute from '../../connectors/PrivateRoute';
<PrivateRoute path="/codes" component={SomePage} />
kontakter/PrivateRoute
import { connect } from 'react-redux';
import { AppState } from 'app-types';
import PrivateRouteComponent from '../../components/PrivateRoute';
const mapStateToProps = (state: AppState) => {
const isSignedIn = state.user.isSignedIn;
return {
isSignedIn
};
};
const PrivateRoute = connect(
mapStateToProps,
null
)(PrivateRouteComponent);
export default PrivateRoute;
komponenter/PrivatRute
import * as React from 'react';
import {
Route,
Redirect,
} from 'react-router-dom';
interface PrivateRouteProps {
// tslint:disable-next-line:no-any
component: any;
isSignedIn: boolean;
// tslint:disable-next-line:no-any
location: any;
}
const PrivateRoute = (props: PrivateRouteProps) => {
const { component: Component, isSignedIn, location, ...rest } = props;
return (
<Route
{...rest}
render={(routeProps) =>
isSignedIn ? (
<Component {...routeProps} />
) : (
<Redirect
to={{
pathname: '/signin',
state: { from: location }
}}
/>
)
}
/>
);
};
export default PrivateRoute;
Feil
(105,18): Type '{ path: string; component: ConnectedComponentClass<typeof SomePage, Pick<SomePageProps, never>>; }' is not assignable to type 'Readonly<Pick<PrivateRouteProps, "location" | "component">>'.
Property 'location' is missing in type '{ path: string; component: ConnectedComponentClass<typeof SomePage, Pick<SomePageProps, never>>; }'.
Svar #1
Feilen oppstår fordi PrivateRouteProps har en obligatorisk egenskap location som ikke er gitt når du bruker PrivateRoute i components/Routes.tsx. Jeg antar at denne location i stedet bør komme fra routeProps som ruteren automatisk sender til render-funksjonen til ruten, slik det ble gjort i det opprinnelige eksemplet. Når dette er fikset, blir en annen feil synlig: components/Routes.tsx sender en paths-egenskap som ikke er deklarert i PrivateRouteProps. Siden PrivateRoute sender videre alle egenskaper den ikke kjenner til Route, bør PrivateRouteProps utvide RouteProps fra react-router slik at PrivateRoute aksepterer alle egenskaper som Route aksepterer.
Her er components/PrivateRoute.tsx etter begge rettelsene:
import * as React from 'react';
import {
Route,
Redirect,
RouteProps,
} from 'react-router-dom';
interface PrivateRouteProps extends RouteProps {
// tslint:disable-next-line:no-any
component: any;
isSignedIn: boolean;
}
const PrivateRoute = (props: PrivateRouteProps) => {
const { component: Component, isSignedIn, ...rest } = props;
return (
<Route
{...rest}
render={(routeProps) =>
isSignedIn ? (
<Component {...routeProps} />
) : (
<Redirect
to={{
pathname: '/signin',
state: { from: routeProps.location }
}}
/>
)
}
/>
);
};
export default PrivateRoute;
