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.

1
  • Would need to see Header & Footer component to see what is supposed to be rendered. Commented May 29, 2019 at 14:34

1 Answer 1

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>
);
Sign up to request clarification or add additional context in comments.

2 Comments

It works!!!!!!!!!!!!!!!! Thanks! Care to explain a bit at const { component: Component, ...rest } = this.props; and <Component {...props} /> please?
Great! const { component: Component, ...rest } = this.props; is about props that RouteAuthenticated receive (i.e. exact, path) and forward rest to <Route {...rest} render={renderRoute} /> and handle component separatelly. <Component {...props} /> is about the component which will be passed to <Route {...rest} render={renderRoute} /> through render method as explained here (til.hashrocket.com/posts/…)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.