0

In my app, I have a state that save userData if the user is logged in, but and I want to redirect him to /dashboard/:id with it id. But when the action is completed, the url is good (e.g : /dashboard/12) but the view is style on /login component..

router version :

"react-router": "^3.2.0",
"react-router-dom": "^4.2.2"

Here is the code :

App.js

import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import Login from './components/Login/Login';
import Register from './components/Register/Register';
import Dashboard from './components/Dashboard/Dashboard';
import './App.css';

class App extends Component {
  render() {
    return (
        <Router>
                <div>
                    <Route path="/register" component={Register} />
                    <Route path="/login" component={Login} />
                    <Route path="/dashboard/:id" component={Dashboard} />
                </div>
        </Router>
    );
  }
}

export default App;

sessionReducer:

import * as types from '../actions/types';
import initialState from './initialState';

export default function sessionReducer(state = initialState, action) {
    switch(action.type) {
        case types.LOG_IN_SUCCESS:
        console.log(action);
            return {
                ...state,
                userData: action.payload
            }
        case types.LOG_IN_FAILED:
            console.log('login failed');
            break;
        default:
            return state;
    }
}

authAction.js :

import { browserHistory } from 'react-router';
import  { Redirect } from 'react-router-dom'
import * as types from './types';
import sessionApi from '../api/SessionApi';
import history from '../history';

export function loginSuccess(userData) {
    return {
        type: types.LOG_IN_SUCCESS,
        payload: userData
    }
}

export function loginFailed() {
    return {
        type: types.LOG_IN_FAILED
    }
}

export function logInUser(credentials) {
    return function(dispatch) {
        return sessionApi.login(credentials)
            .then(response => {
                console.log(response);
                if(response.data) {
                    sessionStorage.setItem('jwt', response.data.authentication_token);
                    dispatch(loginSuccess(response.data));
                    history.push('/dashboard/' + response.data.id);
                } else {
                    dispatch(loginFailed());
                }
            })
            .catch(error => {
                throw(error);
            })
    }
}

The dashboard.js :

import React, { Component } from 'react';
import { withRouter } from 'react-router';
import { connect } from 'react-redux';

class Dashboard extends Component {
    constructor(props) {
        super(props);
        console.log(props);
    }

    componentWillReceiveProps() {

    }

    render() {
        console.log(this.props.userData);
        return(
            <div>
                <h1> Hello user </h1>
            </div>
        );
    }
}

const mapStateToProps = (state) => { 
    return { 
        userData: state.sessionReducer.userData 
    } 
} 

export default withRouter(connect(mapStateToProps)(Dashboard));

And the loginForm.js

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { bindActionCreators } from 'redux';
import { withRouter } from 'react-router'; 
import { connect } from 'react-redux';
import  * as authActions from '../../actions/authActions';


class LoginForm extends Component {
    constructor(props) {
        super(props);
        this.state = {
            email: '',
            password: '',
            errors: {},
            isLoading: false,
        };
    }

    onChange(e) {
        this.setState({
            [e.target.name]: e.target.value
        })
    }

    onSubmit(e) {
        e.preventDefault();
        this.setState({ errors: {}, isLoading: true });
        this.props.actions.logInUser( { data: { user: { email: this.state.email, password: this.state.password }}})
    }

    render() {
        return(
            <div>
                <form onSubmit={this.onSubmit.bind(this)}>
                    <div className="field">
                        <label className="label"> Email </label>
                        <div className="control">
                            <input type="email"
                                   name="email"
                                   value={this.state.email}
                                   onChange={this.onChange.bind(this)}
                                   className="input" />
                        </div>
                    </div>
                    <div className="field">
                        <label className="label"> Mot de passe </label>
                        <div className="control">
                        <input type="password"
                               ref="password"
                               name="password"
                               value={this.state.password}
                               onChange={this.onChange.bind(this)}
                               className="input" />
                        </div>
                    </div>
                    <div className="form-group">
                        <input type="submit" value="Signup" className="button is-primary" />
                    </div>
                    <Link to={{ pathname: '/register' }}>Inscription</Link>
                </form>
            </div>
        );
    }
}

function mapDispatchToProps(dispatch) {
    return {
        actions: bindActionCreators(authActions, dispatch)
    };
}

export default withRouter(connect(null, mapDispatchToProps)(LoginForm));

I just want to render the good component with the right view, does someone know why the Dashboard component doesn't render ?

EDIT

add index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';
import { routerMiddleware } from 'react-router-redux'
import { createStore, applyMiddleware, compose } from 'redux';
import rootReducer from './reducer/rootReducer';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

/*
*   CSS
*/
import './bulma.css';
import './index.css';

/*
*   Render
*/

const store = createStore(
    rootReducer,
    compose(
        applyMiddleware(thunk),
        window.devToolsExtension ? window.devToolsExtension() : f => f
    )
);


ReactDOM.render(
    <Provider store={store}>
        <App /> 
    </Provider>,
    document.getElementById('root'));
registerServiceWorker();
Antonin Mrchd
  • 656
  • 3
  • 9
  • 31
  • Might be worth taking a look at this [question](https://stackoverflow.com/questions/35764510/how-to-implement-dynamic-routing-in-routes-js-for-generated-menu-items-in-sideba) on how to generate dynamic routes with react-router. At the moment it doesn't look like your Routes have anything related to parsing an `id` – aug Oct 09 '17 at 20:27
  • @aug even if i want to redirect to '/' homePage, the view is still on login component. – Antonin Mrchd Oct 09 '17 at 20:35
  • Can you please specify which version of reactRouter you are using? I see `BrowserRouter` which is in v4 and `browserHistory` which is v3. Also, can you please post what is in the file `import history from '../history';` – palsrealm Oct 09 '17 at 22:55
  • @palsrealm I've juste edited my question, and history just import creatBrowserHistory and export default createHistory() – Antonin Mrchd Oct 10 '17 at 06:33
  • Where are you getting `createBrowserHistory` from? AFAIK react-router v4 does not support that any longer. – palsrealm Oct 10 '17 at 15:21

1 Answers1

0

you must to use in router v4:

<BrowserRouter>
  <Switch>
    <Route exact path="/testcolors" component={TestColors} />
  </Switch>
</BrowserRouter>


this.props.history.push('/customers');
stackdave
  • 6,655
  • 9
  • 37
  • 56