j_quelly
j_quelly

Reputation: 1439

React Router will not render Route component unless page is refreshed

It seems my application will not render the component passed to <Route /> unless I refresh the page. What could I be doing wrong?

components/App/index.jsx

// dependencies
import React from 'react';
import PropTypes from 'prop-types';
import { Provider } from 'react-redux';
import { BrowserRouter as Router } from 'react-router-dom'

// components
import Header from '../Header';

// containers
import SidebarContainer from '../../containers/SidebarContainer';
import MainContainer from '../../containers/MainContainer';

const App = ({store}) => (
  <Provider store={store}>
    <Router>
      <div className="wrapper">
        <Header />
        <div className="container-fluid container-fluid--fullscreen">
          <div className="row row--fullscreen">
            <SidebarContainer />
            <MainContainer />
          </div>
        </div>
      </div>
    </Router>
  </Provider>
);
App.propTypes = {
  store: PropTypes.object.isRequired,
};

export default App;

containers/MainContainer.jsx

// dependencies
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Route } from 'react-router-dom'

// components
import Dashboard from '../components/Dashboard';
import List from '../components/List';

// containers
import LoginContainer from './LoginContainer.jsx'

class Main extends Component {
  render() {
    console.log(this.props)
    return(
      <div className="wrapper">
        <Route exact path="/" component={Dashboard} />
        <Route path="/login" component={LoginContainer} />
        <Route path="/users" component={List} />
      </div>
    );
  }
}

const mapStateToProps = (state) => {
  return {
    token: state.authentication.token,
  };
};

const MainContainer = connect(mapStateToProps, null)(Main);

export default MainContainer;

So it seems when I click on a <Link to="/users" /> component my path changes to http://localhost:3000/users but the component does not change from Dashboard to List

I'm also noticing that when I console.log this.props from MainContainer I do not see anything related to router such as this.props.location.pathname --perhaps I'm not structuring my application correctly?

Upvotes: 2

Views: 975

Answers (2)

Ravindra Ranwala
Ravindra Ranwala

Reputation: 21124

I think you have to do little more tweak in your code to make it work. Assuming you use react-router v4, the following should solve your problem.

  import { BrowserRouter, Route, Switch } from 'react-router-dom';

  <Provider store={store}>
    <BrowserRouter>
      <div>
        <Switch>
            <SidebarContainer />
            <MainContainer />
        </Switch>
      </div>
    </BrowserRouter>
  </Provider>

Upvotes: 0

j_quelly
j_quelly

Reputation: 1439

After poking around the react-router issues page on github I found this thread: https://github.com/ReactTraining/react-router/issues/4671

It appears as though the redux connect method blocks context which is required by react-router package.

That being said, the fix for this is to wrap all redux connected components that have router components inside with withRouter() like so:

containers/MainContainer.jsx

// dependencies
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Route, withRouter } from 'react-router-dom' // IMPORT withRouter

// components
import Dashboard from '../components/Dashboard';
import List from '../components/List';

// containers
import LoginContainer from './LoginContainer.jsx'

class Main extends Component {
  render() {
    console.log(this.props)
    console.log(this.context)
    return(
      <div className="wrapper">
        <Route exact path="/" component={Dashboard} />
        <Route path="/login" component={LoginContainer} />
        <Route path="/users" component={List} />
      </div>
    );
  }
}

const mapStateToProps = (state) => {
  return {
    token: state.authentication.token,
  };
};

// WRAP CONNECT METHOD
const MainContainer = withRouter(connect(mapStateToProps, null)(Main)); 

export default MainContainer;

Upvotes: 2

Related Questions