Reputation: 73
All related topics readed, but answer still not found
Hello everyone,
I have a bug in my code and as always I can't find it, so please help me to find the way to make it work.
I have create-react-app where I'm trying to add user authentication. The tutorial I'm looking in: http://jasonwatmore.com/post/2018/09/11/react-basic-http-authentication-tutorial-example
Problem: When I'm logged in I'm seeing "Dashboard" (exact) component, everything is OK. But then I'm clicking on other Link, like 'orders' and etc. I'm getting blank page rendered. No errors on console.
Let's begin from the start.
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { configureFakeBackend } from './_helpers/fake-backend';
configureFakeBackend();
ReactDOM.render((
<App />
), document.getElementById('root'));
App.js file
import React, { Component } from 'react';
import './App.scss';
import MainContent from './components/MainContent.jsx';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { PrivateRoute } from './components/PrivateRoute';
import { LoginPage } from './LoginPage/LoginPage';
class App extends Component {
render() {
return (
<Router>
<Switch>
<PrivateRoute exact path="/" component={MainContent} />
<Route path="/login" component={LoginPage} />
</Switch>
</Router>
);
}
}
export default App;
PrivateRoute.jsx
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
export const PrivateRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
localStorage.getItem('user')
? <Component {...props} />
: <Redirect to={{ pathname: '/login', state: { from: props.location } }} />
)} />
)
MainContent.jsx
import React, { Component } from 'react';
import Sidebar from './Sidebar.jsx';
import Header from './Header.jsx';
import Main from './Main.jsx';
import { userService } from '../_services/user.service';
import { Link } from 'react-router-dom';
class MainContent extends Component {
constructor(props) {
super(props);
this.state = {
user: {},
users: []
};
}
componentDidMount() {
this.setState({
user: JSON.parse(localStorage.getItem('user')),
users: { loading: true }
});
userService.getAll().then(users => this.setState({ users }));
}
render() {
const { user, users } = this.state;
return (
<React.Fragment>
<h1>Hi {user.firstName}!</h1>
{users.loading && <em>Loading users...</em>}
{users.length &&
<ul>
{users.map((user, index) =>
<li key={user.id}>
{user.firstName + ' ' + user.lastName}
</li>
)}
</ul>
}
<p>
<Link to="/login">Logout</Link>
</p>
<Sidebar />
<div id="flexing">
<Header />
<Main />
</div>
</React.Fragment>
);
}
}
export default MainContent;
And at least: Main.jsx
import React from 'react';
import { Switch, Route } from 'react-router-dom';
import Dashboard from './Dashboard';
import Orders from './Orders';
import Routes from './Routes';
import Drivers from './Drivers';
import Settings from './Settings';
const Main = () => (
<main>
<Switch>
<Route exact path='/' component={Dashboard}/>
<Route path='/orders' component={Orders}/>
<Route path='/routes' component={Routes}/>
<Route path='/drivers' component={Drivers}/>
<Route path='/settings' component={Settings}/>
</Switch>
</main>
);
export default Main;
So the Dashboard component will render good, but others render like blank page. Please help to fix it. Waiting for reply.
Justas
Upvotes: 2
Views: 1444
Reputation: 7209
Right so what's happening is that those routes in Main.js are rendered ONLY when App.js renders it. That is, when the path is /
, Main.js is rendered. When it's something else, Main.js isn't rendered and so that Switch component is never hit.
To solve it, you should either remove Main.js and put all of these routes in the top level (you can have two Switch
components in App.js if that helps), or set the path in App.js (for MainComponent) to include all of these. The former is cleaner as the latter could get complicated.
To see that this is the problem, add a default route to App.js and you'll see that the "blank" page you're seeing is because nothing was matching at that level; to set a default, have the path match on *
.
Upvotes: 1