1

I'm making a dashboard, using React Router v4. I have pages such as Sign up, Sign in, Add and List products, Add and List customers.

Authentication pages, Sign up and Sign in pages are with their own layouts, no, header or footer or nav manu. The rest share the same layout design, with header, nav menu and footer.

I've tried this:

// App.tsx

return (
  <Router>
    <Route exact path="/" component={Layout}>
      <Route exact path="/" component={Status} />
      <Route path="/welcome" component={Welcome} />
    </Route>
    <Route path="/signup" component={SignUp} />
    <Route path="/signin" component={SignIn} />
  </Router>
);
// Layout.tsx

return (
  <React.Fragment>
    <Header lastName="Wahaha" />
    <Navbar />
    {children}
    <Footer description="Thanks for visiting!" />
  </React.Fragment>
);

<Header />, <Navbar />, and <Footer /> are not appeared though.

Took a reference from here: Using multiple layouts for react-router components but it doesn't work for me.

Please help.

Swix
  • 1,883
  • 7
  • 33
  • 50

1 Answers1

0

In my projects, I use to create specific routes to handle that. For instance, I have RouteAuthenticated, RouteUnauthenticated, RouteAdmin...

// RouteAuthenticated

import { Redirect, Route } from 'react-router-dom';

class RouteAuthenticated extends React.Component<Props, State> {
    constructor(props) {
        super(props);
        this.state = {
            isAuthenticated: false,
            loading: true,
        };
    }

    async componentDidMount() {
        const isAuthenticated = CHECK IF IS AUTHENTICATED
        this.setState({
            isAuthenticated,
            loading: false,
        });
    }

    render() {
        const { component: Component, ...rest } = this.props;
        const { isAuthenticated, loading } = this.state;
        const renderRoute = props =>
            isAuthenticated === true ? (
                <Layout>
                    <Component {...props} />
                </Layout>
            ) : (
                <Redirect to="/signup" />
            );
        return loading ? null : <Route {...rest} render={renderRoute} />;
    }
}

export default RouteAuthenticated;

This way I take care of wrapping and authentication in a single component.

In App.tsx

// App.tsx

return (
  <Switch>
    <RouteAuthenticated exact path="/" component={Status} />
    <RouteAuthenticated path="/welcome" component={Welcome} />
    <RouteUnauthenticated path="/signup" component={SignUp} /> // or     <Route path="/signup" component={SignUp} />
    <RouteUnauthenticated path="/signin" component={SignIn} /> // or     <Route path="/signin" component={SignIn} />
  </Switch>
);
Pedro Arantes
  • 5,113
  • 5
  • 25
  • 60
  • It works!!!!!!!!!!!!!!!! Thanks! Care to explain a bit at `const { component: Component, ...rest } = this.props;` and `` please? – Swix Jun 01 '19 at 16:10
  • Great! `const { component: Component, ...rest } = this.props;` is about props that `RouteAuthenticated` receive (i.e. `exact`, `path`) and forward `rest` to `` and handle `component` separatelly. `` is about the component which will be passed to `` through `render` method as explained here (https://til.hashrocket.com/posts/z8cimdpghg-passing-props-down-to-react-router-route) – Pedro Arantes Jun 01 '19 at 16:37