0

I have a problem with my react components. Basically my interface should be an SPA, built with ReactJS.

During the implementation of the authentication with auth0-js I also implemented some routes. The layout looks like this:

layout

Whenever I click now on the "Recipes" link, it should redirect to the route "/recipes". However, when I implement the route with <Route path="/recipes" component={Recipes} /> it only renders what is actually returned in the Recipes component. I know that this is correct from what react does. Now, I want to keep the navigation bar but only want to exchange the component below, so I want to change what is below the navigation bar like I did in App.js.

How can I achieve this? Is something about the routes, or components not correct? I do not want to re-render always everything. I also want to keep the style of the whole page. Is there a way to do this?

The whole code can be found here.

bash0ne
  • 394
  • 3
  • 14
  • can you please post the code where you have put the router...you'll have to basically separate the pages(routes) from you static navigation bar – Soham Nakhare Feb 11 '18 at 15:42
  • The code for ther routes is [here](https://github.com/thacomposers/thecookbook/blob/feature/login-reg-form/src/Routes.js) – bash0ne Feb 11 '18 at 16:29

2 Answers2

0

I agree with Jyutzio in that you need to move the Navigation component above the child routes to only change to content of the child routes.

In order to have the Navigation bar update with logged in / logged out state you may want to consider implementing redux. I have a project with nearly the exact requirements as yours - a navigation header that is static.

In my header I have import { connect } from 'react-redux';

At the bottom of the component I use connect before exporting:

function mapStateToProps(state) {
  return { authenticated: state.auth.authenticated };
}

Header = connect(mapStateToProps)(Header);

export default Header;

Then this allows me to check the "authenticated" piece of state and render accordingly.

renderLogoutButton() {
  if(this.props.authenticated) {
    return(
      <li><a onClick={...}>Logout</a></li>
    );
  } else {
    return(
      <li><a onClick={...}>Login</a></li>
    );
  }
}

You will need to setup a reducer, but there are many resources explaining redux setup.


The router (simplified) I have set up as follows:
import Admin from './index';
...
<BrowserRouter>
  <Switch>
    <Route exact path="/login" component={Login} />
    <Route path="/" component={Admin} />
  </Switch>
</BrowserRouter>

index:

import AdminRouter from './admin/admin_router';
...
<div>
  <Menu />
  <div>
    <AdminRouter />
  </div>
</div>

admin_router:

<div>
  <Switch>
    <Route exact path="/" component={Home} />
    <Route exact path="/details" component={AdminDetails} />
    <Route component={PageNotFound} />
  </Switch>
</div>
adam_
  • 261
  • 2
  • 7
-1

If you place your Navigation component above the switch, it will solve your problem.

const Routes = () => (
  <Router history={history} component={Home}>
    <Route component={Navigation}/>
    <Switch>
      <Route exact path="/" render={props => <Home auth={auth} {...props} />} />
      <Route path="/home" render={props => <Home auth={auth} {...props} />} />
      <Route
        path="/callback"
        render={props => {
          handleAuthentication(props);
          return <Callback {...props} />;
        }}
      />
      <Route component={NotFound} />
    </Switch>
  </Router>
);
Jyutzio
  • 39
  • 4
  • I also thought about that but as I have to check if the user is logged in or not, how can I do this then? See the `isAuthenticated()` calls in [Home.js](https://github.com/thacomposers/thecookbook/blob/feature/login-reg-form/src/Home.js) – bash0ne Feb 11 '18 at 18:29