React Router Basic & Implementation On React App
Most React applications have a couple pages such as Home, Contact, About etc. When we create multiple pages of an application we need to interact with our application with React Router to serve users to have easy access between our Web pages.
For example;
When we make a request to the home page , we make that initial request to the server then we get a response which is an index.html page and it will go to the browser. Then React realizes that you want to be on the Home page and it will load up a home component. Let’s think like App.js is our root component which is rendering the Home page component showing in the browser. React will inject the Home component inside the App.js to show users when they go to /home page.
Any subsequent request we make inside the Home component like Navbar, we click a link to go to an About page. How does that work ?
When we make that request but it does not go all the way to the server. Instead React router intercept stopping to go to the server and it will inject about components into parent components App.js. It stops the request from going to the server and coming back to our component. Because we just need an index.html file to visit different pages. We don’t need to go every time to the server to make this request. This is basically How React Router works and why we need them in our app.
Let’s go deeper about how to implement a react router in our app below .
EXPLAINING ABOUT HOW TO IMPLEMENT ROUTES IN DIFFERENT PAGES IN APP.
I wrapped my app component with router component. This means any child component of app component has access routes. Every component in app wrapped in router. Those routes which is associated with related components. When the user navigates to a specific routes they will only see the components that which I set up inside our routes tags. Provide component also provided by react-redux package. When I wrapped our app component to have access to our global state or store but It doesn’t mean it connects all my components to redux store. This is what I want with. In this way I can choose which properties of the global state and my components that I can have access via mapStateToProps or MapDispatchToProps.
index.jsimport React from 'react';import ReactDOM from 'react-dom';import {createStore, applyMiddleware, compose} from 'redux'import thunk from 'redux-thunk'import { Provider } from 'react-redux'import {BrowserRouter as Router} from 'react-router-dom'import playerReducer from './reducers/playerReducer'import App from './App';const composeEnchancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;const store = createStore(playerReducer,composeEnchancers(applyMiddleware(thunk)))ReactDOM.render(<Provider store={store}>
// Any component that I wrapped in provider will have access to our Redux Store.
I must call store in provider as I call in variable<Router> <App /></Router></Provider>,document.getElementById('root'));render () {*return* (<div><Switch>
Rendering PlayerInput
If we are going to use a route tag for setting up for Player input What would it make sense what path would it make sense given that component?
<Route path='/players/new'
What component it should render in this route when we go.. /player/new ?
<Route path='/players/new' component={PlayerInput}
We don’t see that on our home page yet .Because we said we want to see our Player input when When we go specific for that path.
Rendering Players…
If we want to see players’ components only when we go to a specific route we can set up just a specific route. We don’t need to do render like component={PlayerInput} for this route.
What is the difference between the PlayerInput & Player component that is gonna lead us for Players?
Because when we set up our player container we pass props and we map over the props to render our players. So the route does not know magically about this convention. We set up our players like regular functional components that receive props. All We have to do passing props to routes.
<Route path='/players' render={() => Accounts players={this.props.players}
We want to use render takes in a function whereas this just points it to the component or render is going to take in a function and syntax is then to pass in this component in that regular component syntax. When you use render and when you want to pass in props through a route the actual component is going to look just as it did as if you were rendering it outside. It’s just inside to props. But if we write code like this it’s gonna render Players also in playersInput. Which we don’t want to do.
<Route path='/players/new' component={PlayerInput}<Route path='/players' render={() => Accounts players={this.props.players}
The reason is ; When the route sees players for each route it renders players both routes. We have to pass the exact keyword to solve this problem. It means render players the route exactly matching path=’/players’
<Route exact path='/players' render={() => Accounts players={this.props.players}
It’s not a nested route but the path looks like a nested route
Rendering specific Player component….
We are looking at what this path should be for a specific Player. We can use this syntax that makes it a dynamic path. We want you to be a player and there will be some sort of ID here.
<Route path=’/players/:id’
What we are going to need to render the information about a specific player? What is the problem we are going to see here?
<Route path='/players/:id' render={(routerProps) =>< Player {...routerProps} players={this.props.players}/> }/>
We have to set up a function in Player.js to find a specific player for route. We are not rendering the components anymore directly. They will be conditionally based on the URL. We are rendering through components instead of rendering. Components get automatically getting props. {…routerProps} passing the props in for a specific player we pass in {…routerProps} these props in addition to the props that we have to set up. This will automatically add these props into the props object which this component is receiving.