Here is an example from react-router for how to add a component for protected routes:
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
I have tried to implement this functionality in my Typescript project, using the example above as inspiration.
import * as React from 'react';
import {
Route,
Redirect,
} from 'react-router-dom';
interface PrivateRouteProps {
component: React.Component; // passed as prop
isSignedIn: boolean; // injected as prop by redux
location: Location;
}
const PrivateRoute = (props: PrivateRouteProps) => {
const { component: Component, isSignedIn, location } = props;
return (
<Route
{...rest}
render={(routeProps) =>
isSignedIn ? (
<Component {...routeProps} />
) : (
<Redirect
to={{
pathname: '/signin',
state: { from: location }
}}
/>
)
}
/>
);
};
export default PrivateRoute;
I get the following errors
[ts] Cannot find name 'rest'.
any
[ts] JSX element type 'Component' does not have any construct or call signatures.
const Component: React.Component<{}, {}, any>
propTypes = { //// key is the name of the prop and // value is the PropType } export default Count; PropTypes are also objects with a key and a value pair where the 'key' is the name of the prop while the value represents the type or class by which they are defined.
Use the spread syntax (...) to pass an object as props to a React component, e.g. <Person {... obj} /> . The spread syntax will unpack all of the properties of the object and pass them as props to the specified component. Copied!
Props are immutable, while state is mutable Although a component is not allowed to change its props, it is responsible for the props of its child components down the component tree. On the other hand, state is mutable. A stateful component changes its state every time users interact with the app.
1) You haven't pulled the remaining props from your destructuring operator, to get the rest of the props, you'll need this:
const { component: Component, isSignedIn, location, ...rest } = props;
2) Component
isn't what you think it is here, it is an interface for class element construction, but you're using it to define a type. If you're looking to enforce it as an Element, you'll want to use JSX.Element
.
Ultimately you should be left with:
import * as React from 'react';
import {
Route,
Redirect,
} from 'react-router-dom';
interface PrivateRouteProps {
component: JSX.Element; // passed as prop
isSignedIn: boolean; // injected as prop by redux
location: Location;
}
const PrivateRoute = (props: PrivateRouteProps) => {
const { component, isSignedIn, location, ...rest } = props;
return (
<Route
{...rest}
render={(routeProps) =>
isSignedIn ? (
<Component {...routeProps} />
) : (
<Redirect
to={{
pathname: '/signin',
state: { from: location }
}}
/>
)
}
/>
);
};
export default PrivateRoute;
import React, { forwardRef, ReactNode } from "react"
interface ICardProps {
children: ReactNode;
className?: string;
[props: string]: any;
}
const Card = forwardRef<HTMLDivElement, ICardProps>(( props, ref ) => {
const { className, children, ...rest } = props;
return <div ref={ref} className={className} {...rest}>{children}</div>
})
export default Card;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With