Inside my React JS project, I am working on the PrivateRoutes. 
I have gone through this example of private routing and authenticating using react-router-dom. 
https://reacttraining.com/react-router/web/example/auth-workflow
According to this documentation, they have created a PrivateRoute as a stateless component. 
But my requirement is to convert it to stateful React component as I want to connect my PrivateRoute component to redux store.
Here is my code.
stateless component
import React from 'react';
import {Route, Redirect} from 'react-router-dom';
import {auth} from './Authentication';
const PrivateRoute = ({ component: Component, ...rest }) => (
    <Route
      {...rest}
      render={props =>
        auth.isAuthenticated ? (
          <Component {...props} />
        ) : (
          <Component {...props} action="login"/>
        )
      }
    />
  );
  export default PrivateRoute;
I converted this component to stateful React component like this.
stateful React component
import React from 'react';
import {Route, Redirect} from 'react-router-dom';
import {auth} from './Authentication';
import {connect} from 'react-redux';
  class PrivateRoute extends React.Component {
    render({ component: Component, ...rest }) {
      return (
        <Route
          {...rest}
          render={props =>
            this.props.customer.isAuthenticated ? (
              <Component {...props} />
            ) : (
              <Component {...props} action="login"/>
            )
          }
        />
      );
    }
  }
  export default connect(state => state)(PrivateRoute);
Here, I am reading the data from redux store to check whether the user is authenticated or not.
But the way I am converting the stateless component to stateful isn't correct.
Am I passing the arguments  render({ component: Component, ...rest }) correctly?
Will connecting the PrivateRoute with redux store create any problem with props as state=>state will map state to props as well as ...rest will have props object?
Not sure what is happening inside the code.
Update AppRouter.js
import React from 'react';
import {BrowserRouter, Route, Switch} from 'react-router-dom';
import {TransitionGroup, CSSTransition} from 'react-transition-group';
import PrivateRoute from './PrivateRoute';
import HomePage from './../components/HomePage';
import AboutUs from './../components/AboutUs';
import ContactUs from './../components/ContactUs';
import PageNotFound from './../components/PageNotFound';
import RestaurantList from '../components/RestaurantList';
import RestaurantMenu from '../components/RestaurantMenu';
import UserDetails from '../components/UserDetails';
import OrderConfirmation from '../components/OrderConfirmation';
import CustomerAccount from '../components/CustomerAccount';
import Logout from '../components/sections/Logout';
export default () => {
    return (
        <BrowserRouter>
            <Route render={({location}) => (
                <TransitionGroup>
                    <CSSTransition key={location.key} timeout={300} classNames="fade">
                        <Switch location={location}>
                            <Route path="/" component={HomePage} exact={true}/>
                            <Route path="/about" component={AboutUs} />
                            <Route path="/contact" component={ContactUs} />
                            <Route path="/restaurants" component={RestaurantList} />
                            <Route path="/select-menu" component={RestaurantMenu} />
                            <PrivateRoute path="/user-details" component={UserDetails} />
                            <PrivateRoute path="/order-confirmation" component={OrderConfirmation} />
                            <PrivateRoute path="/my-account" component={CustomerAccount} />
                            <PrivateRoute path="/logout" component={Logout} />
                            <Route component={PageNotFound} />
                        </Switch>
                    </CSSTransition>
                </TransitionGroup>
            )} />
        </BrowserRouter>
    );
}
                In general, converting a stateless functional component (SFC) to a Component is done like this:
Create the class shell for it.
Copy the SFC's body to the render method. If the SFC was an arrow function, add a return as necessary to render.
Change any references to props in the render method to this.props (or just add const { props } = this; at the top). SFCs receive their props in their arguments, but a component receives them as arguments to its constructor; the default constructor will save them as this.props.
In your case, it's using destructuring on its arguments, so you could do the same with this.props on the right-hand side of the destructuring:
 const { component: Component, ...rest } = this.props;
That's it. In your code, you've added parameters to the render function, but it doesn't get called with any arguments, and you've only changed props to this.props a bit haphazardly (including changing auth.isAuthenticated to this.props.customer.isAuthenticated for some reason).
So applying 1-3 above:
// #1 - the shell
class PrivateRoute extends React.Component {
  // #2 - `render`, with the body of the SFC inside
  render() {
    // #3 - destructure `this.props`
    const { component: Component, ...rest } = this.props;
    // #2 (part 2) - add `return`
    return <Route
      {...rest}
      render={props =>
        auth.isAuthenticated ? (
          <Component {...props} />
        ) : (
          <Component {...props} action="login"/>
        )
      }
    />;
  }
}
                        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