1

i'm new with Reactjs and for some reasons i'm working on a small application for learning purpose.

I'm using react-router-dom to navigate between different components.

The idea is when the user click to logout, the App Component should detect the logout event inside the componentWillUpdate() method and then redirect the user to Login Component.

The error is: enter image description here

Routes.js

import React from 'react';
import { BrowserRouter, Route, Switch, Link, NavLink } from 'react- 
router-dom';
import Login from '../Components/LoginComponent/Login';
import AddNoteForm from "../Components/AddNoteForm";


const AppRouter = () => (
<BrowserRouter>
        <Switch>
            <Route path="/" component={AddNoteForm} exact={true} />
            <Route path="/login" component={Login} exact={true} />
        </Switch>
</BrowserRouter>
);

export default AppRouter;

Index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import configureStore from './Redux/Store/ConfigureStore';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';


const store = configureStore();


const jsx = (
<Provider store={store}>
    <MuiThemeProvider>
        <App />
    </MuiThemeProvider>
</Provider>
);

ReactDOM.render(jsx, document.getElementById('root'));
registerServiceWorker();

App.js

import React, { Component } from 'react';
import './App.css';
import { Grid, Col, Row } from 'react-bootstrap';
import Navigation from "./Components/Navigation";
import AddNoteForm from "./Components/AddNoteForm";
import Clock from "./Components/Clock";
import { connect } from 'react-redux';
import AppRoutes from "./Routes/Routes";

class App extends Component {

constructor(props) {
super(props);
}
  componentWillUpdate(nextProps, nextState) {

if (nextProps.store.user.email === null || nextProps.store.user.email 
== undefined) {
  this.props.history.replace('/login');
}

 }


 render() {
 return (
  <div className="App">
    <header className="App-header">
      <h1 className="App-title">Welcome to this Learing React 
Application.</h1>
    </header>
    <div className="App-intro" >
      <Navigation></Navigation>
      <Grid>
        <Row className="show-grid">
          <AppRoutes />
        </Row>
      </Grid>
    </div>
  </div>
  );
 }
}

const mapStateToProps = (store) => {
  return { store };
};

export default connect(mapStateToProps)(App);

Package.json

    {
      "name": "first-react",
      "version": "0.1.0",
      "private": true,
      "dependencies": {
        "install": "^0.11.0",
        "material-ui": "^0.20.0",
        "npm": "^6.0.0",
        "react": "^16.2.0",
        "react-bootstrap": "^0.32.1",
        "react-dom": "^16.2.0",
        "react-redux": "^5.0.7",
        "react-router-dom": "^4.2.2",
        "react-scripts": "1.1.1",
        "react-spinner": "^0.2.7",
        "react-spinners": "^0.3.2",
        "react-toastify": "^4.0.0-rc.5",
        "redux": "^4.0.0",
        "redux-thunk": "^2.2.0",
        "uuid": "^3.2.1"
      },
      "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build",
        "test": "react-scripts test --env=jsdom",
        "eject": "react-scripts eject"
      }
    }
BenFarhat Souhaib
  • 219
  • 2
  • 4
  • 14
  • I just read the title but I saw a big mistake here `this.props` is supposed to be read only. – 3Dos Apr 28 '18 at 15:02

3 Answers3

3

Your App component is not being wrapped with BrowserRouter. You need to wrap it somewhat like this:

const Routes = () => (
    <Switch>
        <Route path="/" component={AddNoteForm} exact={true} />
        <Route path="/login" component={Login} exact={true} />
    </Switch>
);

const jsx = (
<Provider store={store}>
    <MuiThemeProvider> 
       <BrowserRouter>
         <div>
           <AppRouter />
           <Route component={App} />
         </div>
       <BrowserRouter>
    </MuiThemeProvider>
</Provider>
);
Tomasz Mularczyk
  • 27,156
  • 17
  • 99
  • 146
  • Can you please explain it in a better way, should I change Routes.js file like you mentioned ? – BenFarhat Souhaib Apr 29 '18 at 09:48
  • @BenFarhatSouhaib First thing is that your `App` component must be a child of `BrowserRouter` to use `history`. Second thing - you need to pass `history` prop somehow. You can use `withRouter` HOC or use `Route` component which will pass it. – Tomasz Mularczyk Apr 29 '18 at 09:54
1

In order to have the history in your props, you can use withRouter.
Update the App.js file as follows:

import { withRouter } from 'react-router'

...

export default withRouter(connect(mapStateToProps)(App));
Evhz
  • 7,265
  • 7
  • 39
  • 61
0

Please use https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/Redirect.md, you can just render component in App.js

 componentWillUpdate(nextProps, nextState) {

if (nextProps.store.user.email === null || nextProps.store.user.email 
== undefined) {
  return <Redirect to="/login" />
}
Milos Mosovsky
  • 2,447
  • 1
  • 12
  • 16