I am learning Redux, and with the new changes in react-router-dom I am a bit confused. I have these files:
Index.js
import React from 'react';
import { Provider } from 'react-redux';
import ReactDOM from 'react-dom';
// import { AppContainer } from 'react-hot-loader';
import App from './containers/App';
import store from './store';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root'),
);
App.js
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as actionCreators from '../actions/actionCreators';
import Main from '../components/Main';
function mapStateToProps(state) {
return {
search: state.search,
navigation: state.navigation,
};
}
export function mapDispatchToProps(dispatch) {
return bindActionCreators(actionCreators, dispatch);
}
const App = connect(mapStateToProps, mapDispatchToProps)(Main);
export default App;
Finally, Main.js
import React from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import Header from './Header';
import Footer from './Footer';
import Listing from './Listing';
import SingleListing from './SingleListing';
const Main = () => (
<Router>
<div className="wrapper">
<Header />
<Route exact path="/" component={Listing} />
<Route path="/list" component={SingleListing} />
<Footer />
</div>
</Router>
);
export default Main;
This code works just fine, when I go to localhost:3000/list or if I click on a it works.
However I have the feeling that I am doing something wrong and that the correct way should be to wrap in to the inside index.js
so I should do something like this:
<Router>
<Provider store={store}>
<App />
</Provider>,
</Router>
document.getElementById('root'),
And then in Main.js
<div className="wrapper">
<Header />
<Route exact path="/" component={Listing} />
<Route path="/list" component={SingleListing} />
<Footer />
</div>
However when I do this, if I go directly to the link localhost/list I can see the component, but if I clink on any link nothing happens.
I am confused on how to correctly use the router with redux. This is the code I am using inside reducers/index.js
import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';
import search from './search';
import navigation from './navigation';
const rootReducer = combineReducers({ search, navigation, routing: routerReducer });
export default rootReducer;
I have researched this site and many tutorials online and on youtube, but I don't understand if I am doing correctly in my code, I know it works but I am interested in learning if this is the correct way. Thank you!
They are technically three different packages: React Router, React Router DOM, and React Router Native. The primary difference between them lies in their usage. React Router DOM is for web applications and React Router Native is for mobile applications made with React Native.
React Router DOM enables you to implement dynamic routing in a web app. Unlike the traditional routing architecture in which the routing is handled in a configuration outside of a running app, React Router DOM facilitates component-based routing according to the needs of the app and platform.
react-dom : ReactDOM.render has been deprecated. Using it will warn and run your app in React 17 mode. react-dom : ReactDOM.hydrate has been deprecated. Using it will warn and run your app in React 17 mode.
Introduction Redux and React Router are two of the most used React libraries. Redux is used for app state management, while React Router is used for routing. In a majority of apps, it's necessary to communicate between the app state and the router.
You can use the connected-react-router library (formerly known as react-router-redux ). Their Github Repo details the steps for the integration. Once the setup is complete, you can now access the router state directly within Redux as well as dispatch actions to modify the router state within Redux actions.
React Router DOM enables you to implement dynamic routing in a web app. Unlike the traditional routing architecture in which the routing is handled in a configuration outside of a running app, React Router DOM facilitates component-based routing according to the needs of the app and platform.
You can see the use of the useHistory hook to gain access to the history instance of the router. In pre-hooks versions of React Router, you had to pass any component that required access to the router state through a withRouter HoC (higher-order component).
Yes, you are writing router correctly. Your concern is understandable. Until the version 4.0.0, react-router
had a different way to declare routes. You would define a Router like in your second example, but instead of defining routes in the components, you would define routes within the Router. Here's an example of react-router
before 4.0.0:
App.js:
//<boilerplate imports>
import Home from './components/Home';
import router from './router';
import './index.css';
ReactDOM.render(
<Router router='router' history='browserHistory'>
</Router>,
document.getElementById('root')
);
router.js:
//<boilerplate imports>
import Photographer from './components/photographer/Photographer';
import Developer from './components/developer/Developer';
import Home from './components/Home';
export default (
<Route path="/">
<IndexRoute component={Home} />
<Route path="photographer" component={Photographer} />
<Route path="developer" component={Developer} />
</Route>
);
You would define the router and all the routes, subroutes, and components to use in one place, and you would end up providing that to ReactDOM.render()
Having said that, the first way to do things is correct and is the way the people behind React Router expect people to use the interface.
Regarding the last question, are you getting an error with that code using react-router-redux
? Looking at this for reference, it seems to be correct.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With