react-router
router-dom
react-router-native
react-router
provides basic functions and components for working in two environments (Browser and react-native)
react-router-dom
. react-router-dom
exports all functions from react-router
so we only need to install react-router-dom
.
npm install --save react-router-dom
BrowserRouter
and HashRouter
components. BrowserRouter
- should be used when you are processing dynamic requests on the server, and use HashRouter
when you have a static web site.
BrowserRouter
, but if your site is located on a static server ( from translation as github pages ), then using HashRouter
is a good solution to the problem.
BrowserRouter
.
history
object that stores the path to the current location [1] and redraws the site interface when some path changes occur.
history
object through the context, so they must be rendered inside the Router component.
import { BrowserRouter } from 'react-router-dom'; ReactDOM.render(( <BrowserRouter> <App /> </BrowserRouter> ), document.getElementById('root'))
<App/>
component which we divide into two parts. <Header/>
which will contain the navigation links and <Main/>
which will contain the content of the routes.
// <Router> const App = () => ( <div> <Header /> <Main /> </div> )
<Route/>
component is the main building block of React Router. In that case, if you need to render an element depending on the pathname of URLs, then you should use the <Route/>
component
<Route />
takes a path
in the form of prop which describes a specific path and maps to the location.pathname.
<Route path='/roster'/>
<Route/>
matches the location.pathname that starts with / roster [2]. When the current location.pathname is mapped positively to the prop path, the component will be rendered, and if we cannot match them, then Route does not render anything [3].
<Route path='/roster'/> // location.pathname '/', prop path // location.pathname '/roster' '/roster/2', prop path // exact prop. '/roster', // '/roster/2' <Route exact path='/roster'/>
http://www.example.com/my-projects/one?extra=false
/my-projects/one
path-to-regexp
package compiles a prop path into a regular expression and matches it against location.pathname. Path lines have more complex formatting options than explained here. You can read the documentation .
match
object is created that contains properties:
Route
component can be anywhere in the router, but sometimes you need to determine what to render in the same place. In this case, you should use the Route grouping component <Switch/>
. <Switch/>
iteratively passes through child components and renders only the first one that matches location.pathname.
<Switch> <Route exact path='/' component={Home}/> {/* /roster /roster/:number /roster */} <Route path='/roster' component={Roster}/> <Route path='/schedule' component={Schedule}/> </Switch>
<Route path='/page' component={Page} /> const extraProps = { color: 'red' } <Route path='/page' render={(props) => ( <Page {...props} data={extraProps}/> )}/> <Route path='/page' children={(props) => ( props.match ? <Page {...props}/> : <EmptyPage {...props}/> )}/>
Route
item. match
is the path
mapping object with location.pathname
, the location
object [6] and the history
object (created by the route itself) [7].
<Switch/>
component and the <Route/>
component inside our <Main/>
component that will put the generated HTML that satisfies the path
mapping inside.
<Main/>
DOM node (node)
import { Switch, Route } from 'react-router-dom' const Main = () => ( <main> <Switch> <Route exact path='/' component={Home}/> <Route path='/roster' component={Roster}/> <Route path='/schedule' component={Schedule}/> </Switch> </main> )
Route
for the main page contains prop exact
, thanks to which the paths are compared strictly.
/roster/:number
not included in <Switch/>
. Instead, it will be rendered by the <Roster/>
component that is rendered whenever the path starts with /roster
.
Roster
component, we will create components for two paths:
const Roster = () => ( <Switch> <Route exact path='/roster' component={FullRoster}/> <Route path='/roster/:number' component={Player}/> </Switch> )
<Roster/>
can be rendered with a header that will be displayed in all routs that start with /roster
.
const Roster = () => ( <div> <h2>This is a roster page!</h2> <Switch> <Route exact path='/roster' component={FullRoster}/> <Route path='/roster/:number' component={Player}/> </Switch> </div> )
path
.
:number
part of the string in /roster/:number
means that the part of the path
after /roster/
will be received as a variable and saved in match.params.number
. For example, the path /roster/6
generate the following object with parameters:
{ number: '6' // }
<Player/>
component will use props.match.params
to get the necessary information that needs to be rendered.
// API import PlayerAPI from './PlayerAPI' const Player = (props) => { const player = PlayerAPI.get( parseInt(props.match.params.number, 10) ) if (!player) { return <div>Sorry, but the player was not found</div> } return ( <div> <h1>{player.name} (#{player.number})</h1> <h2>{player.position}</h2> </div> )
<Player/>
component, our website uses others like <FullRoster/>
, <Schedule/>
and <Home/>
.
const FullRoster = () => ( <div> <ul> { PlayerAPI.all().map(p => ( <li key={p.number}> <Link to={`/roster/${p.number}`}>{p.name}</Link> </li> )) } </ul> </div> ) const Schedule = () => ( <div> <ul> <li>6/5 @ </li> <li>6/8 vs </li> <li>6/14 @ </li> </ul> </div> ) const Home = () => ( <div> <h1> !</h1> </div> )
<Link/>
component that prevents the reboot. When we click on <Link/>
it updates the URL and the React Router renders the necessary component without refreshing the page.
import { Link } from 'react-router-dom' const Header = () => ( <header> <nav> <ul> <li><Link to='/'>Home</Link></li> <li><Link to='/roster'>Roster</Link></li> <li><Link to='/schedule'>Schedule</Link></li> </ul> </nav> </header> )
<Link/>
uses prop to
describe the URL where to go. Prop to can be a string or a location object (which consists of the pathname, search, hash, state properties). If it is a string, then it is converted to a location object.
<Link to={{ pathname: '/roster/7' }}>Player #7</Link>
<Link/>
components must be absolute [4].
<BrowserRouter.>, <Route.>, and <Link.>
), But there are a few more components and props that are not covered here. Fortunately, the React Router has excellent documentation where you can find a more detailed explanation of the components and props. Also, the documentation provides working examples with source code.
// location { pathname: '/', search: '', hash: '', key: 'abc123' state: {} }
<Route/>
component without a path. This is useful for passing methods and variables that are stored in context
.
children
then the route will be rendered, even there is a path and the location.pathname does not match.
<Route/>
and <Link/>
. Relative <Link/>
more complex than they might seem, they should be resolved using their parent match
object, not the current URL.
render
and component
. Component uses React.createElement
to create the component, while render
used as a function. If you defined the inline function and passed props
through it, it would be much slower than using the render
function.
<Route path='/one' component={One}/> // React.createElement(props.component) <Route path='/two' render={() => <Two />}/> // props.render()
<Route/> <Switch/>
components can both use prop location. This allows you to map them to the path, which is actually different from the current URL.
staticContext
, but it is only useful when rendering on the server.Source: https://habr.com/ru/post/329996/