route
When the application becomes complex, it needs to be processed and displayed in blocks. In the traditional mode, we divide the whole application into multiple pages, and then connect them through URL However, there are some problems with this method. Every time you switch pages, you need to resend all requests and render the whole page, which will not only affect the performance, but also lead to the re execution of the whole JavaScript and the loss of state
SPA
concept
Single Page Application. The whole application loads only one page (entry page). In the subsequent interaction with users, the structure and content are dynamically generated on this single page through DOM operation
advantage
- Better user experience (less waiting and blank caused by request and rendering and page Jump), and faster page switching
- Re front end, data and page content are completed by asynchronous request (ajax)+DOM operation, and the front end handles more business logic
shortcoming
- Slow first entry processing
- Not conducive to SEO (search engine optimization)
Page switching mechanism of SPA
Although the content of SPA is dynamically processed through JavaScript on one page, it still needs to be displayed in different situations according to the needs. If it only depends on the internal mechanism of JavaScript, the logic will become too complex. Through the combination of JavaScript and URL: Javascript processes different logic according to the change of URL, You only need to change the URL during the interaction In this way, the way to associate different URLs with the corresponding logic of JavaScript is routing, which is essentially consistent with the idea of back-end routing
Front end routing
The front-end route only changes the URL or part of the URL, but it will not directly send the request. It can be considered that it only changes the URL on the browser address bar. JavaScript handles the change of the URL through various means, and then dynamically changes the current page structure through DOM operation
- The change of URL will not send HTTP request directly
- The business logic is completed by the front-end JavaScript
At present, the main modes of front-end routing are:
-
URL Hash based routing
-
Routing based on HTML5 History API
website: https://developer.mozilla.org/zh-CN/docs/Web/API/History_API
React Router
website: https://reacttraining.com/react-router/
React Router provides a variety of routing libraries in different environments
- web
- native
Web based React Router
The web-based React Router is: React Router dom
install
npm i -S react-router-dom
assembly
hash of url
-
The hash of the URL is the anchor point, which essentially changes the window href attribute of location;
-
We can directly assign location Hash to change the href, but the page does not refresh
-
<html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <a href="#View1 "> view1</a> <a href="#View2 "> view2</a> <a href="#View3 "> view3</a> <div id="view"></div> <script> function getHash(){ console.log(window.location.hash); view.innerHTML = window.location.hash; } getHash(); window.addEventListener('hashchange',getHash) </script> </body> </html>
In the above case, the button page will display the corresponding anchor point, and the console will also output the corresponding anchor point
Routing type: BrowserRouter component and HashRouter component. They have to wrap all the contents
BrowserRouter component
Routing component based on HTML5 History API
Import: import {browserouter} from "react router DOM";
HashRouter component
URL Hash based routing component
Import: import {hashrouter} from "react router DOM";
Route component
This component is used to set and apply a single Route information. The region where the Route component is located is the region that the subsequent component will display when the URL matches the path attribute set by the current Route
path attribute
Matching url; (the way to match URLs is not equal, but starts with the given url)
component properties
When the url matches the previous path, the displayed content is written in the compinent
exact property
The exact attribute indicates that the route uses the exact matching mode. In the non-exact mode '/' matches all routes starting with '/'
<!-- src/view/index.js --> import React from "react"; export default function IndexPage(){ return <h1>home page</h1> } <!-- src/view/about.js --> import React from "react"; export default function AboutPage(){ return <h1>About us</h1> } <!-- src/view/aboutMore.js --> import React from "react"; export default function AboutMorePage(){ return <h1>details</h1> }
<!-- src/index.js --> import React from 'react'; import ReactDOM from 'react-dom'; // import { HashRouter } from "react-router-dom"; import { BrowserRouter } from "react-router-dom"; import './index.css'; import App from './App'; ReactDOM.render( <BrowserRouter > <App /> </BrowserRouter>, document.getElementById('root') );
<!-- src/app.js --> import React from 'react'; import {Route} from "react-router-dom"; import IndexPage from "./view/index"; import AboutPage from "./view/about"; import AboutMorePage from "./view/aboutMore"; function App() { return ( <div className="App"> <Route path='/' exact component={IndexPage} /> <Route path='/about' exact component={AboutPage} /> <Route path='/about/more' exact component={AboutMorePage} /> </div> ); } export default App;
Link assembly
The Link component is used to handle similar functions of a Link (it will generate an a tag in the page), but it should be noted here that the react router DOM intercepts the default action of the actual a tag, and then processes it according to all the used routing modes (Hash or HTML5). The URL is changed, but no request will occur, At the same time, the corresponding components are displayed in the specified position according to the settings in Route
effect:
Change url only
to attribute
a similar attribute in the href to tag
<!-- src/component/nav.js --> import React from 'react'; import { Link } from "react-router-dom"; export default function Nav(){ return( <nav> <Link to='/'>home page</Link> <span> | </span> <Link to='/about'>About us</Link> <span> | </span> <Link to='/about/more'>details</Link> <span> | </span> </nav> ) }
<!-- src/app.js --> import React from 'react'; import {Route} from "react-router-dom"; import IndexPage from "./view/index"; import AboutPage from "./view/about"; import AboutMorePage from "./view/aboutMore"; import Nav from "./component/nav"; // path: the way to match the url is not equal, but starts with the given url function App() { return ( <div className="App"> {/* link The component only changes the url */} <Nav /> {/* path Properties: matching URLs */} <Route path='/' exact component={IndexPage} /> <Route path='/about' exact component={AboutPage} /> <Route path='/about/more' exact component={AboutMorePage} /> </div> ); } export default App;
Pass props
If Route uses component to specify components, props cannot be used
Render attribute: specify the rendering function through the render attribute. The render attribute value is a function. When the route matches, specify this function for rendering
import React, {useState} from 'react'; let [user,setUser] = useState('router'); <Route path='/' exact render={()=>{ return <IndexPage user={user} setUser={setUser}/> }} /> <!--src/view/index.js--> import React from "react"; export default function IndexPage(props){ console.log(props); let {user,setUser} = props; return <h1> <a onClick={()=>{ setUser('React No') }}>gossip</a> home page </h1> }
Dynamic routing
In order to handle the access of the above dynamic routing address, a special path needs to be configured for the Route component
Purpose: to pass different parameters to different components
Routing parameters:
-
History: history and some operations routed to us
Go back to the previous step
goForward step forward
push: modify the current url
replace: modify the current url
// history.push(’/about’); // The fallback function of this is available History will be added
// history.replace(’/about’); // There is no turning back History will not be added
-
location: get some information about the current url
- pathname – current URL
- search – interface parameters
- state – parameters passed when jumping route
-
match: relevant rules for current route matching
- params – parameters passed from dynamic routing
<!-- src/view/index.js --> import React from "react"; import { NavLink, Link } from "react-router-dom"; export default function IndexPage(){ return ( <div> <h1>Message list</h1> <Link to='/list/1'>1</Link> <span> | </span> <Link to='/list/2'>2</Link> <span> | </span> <Link to='/list/3'>3</Link> <span> | </span> <Link to='/list/4'>4</Link> <span> | </span> <Link to='/list/5'>5</Link> <span> | </span> <Link to='/list/6'>6</Link> </div> ) }
<!-- app.js --> import React from 'react'; import { Route,Switch } from "react-router-dom"; import IndexPage from "./view/index"; import Page404 from "./view/Page404"; function App() { return ( <div className="App"> <Switch> <Route path='/list/:page' exact render={(props)=>{ return <IndexPage {...props} ></IndexPage> }}></Route> <Page404 component={Page404}></Page404> </Switch> </div> ); } export default App;
In the above case, note that the path is written dynamically
NavLink assembly
NavLink is similar to Link, but it provides two special properties to handle page navigation
activeStyle
Activate the style in activeStyle when the current URL matches the to in NavLink
activeClassName
Similar to activeStyle, but className is activated
<!-- src/component/nav.js --> import React from 'react'; import { NavLink } from "react-router-dom"; export default function Nav(){ return( <nav> <NavLink to='/' exact activeClassName='active' activeStyle={{ color:'red' }} >home page</NavLink> <span> | </span> <NavLink to='/about' exact activeClassName='active about' activeStyle={{ color:'red' }} >About us</NavLink> <span> | </span> <NavLink to='/about/more' exact activeClassName='active about more' activeStyle={{ color:'red' }} >details</NavLink> <span> | </span> </nav> ) }
isActive
By default, the settings of URL and to are matched. The activation logic can be customized through isActive. isActive is a function that returns a Boolean value
Switch component
This component renders only the first matched component
<!-- app.js --> import React from 'react'; import { Route,Switch } from "react-router-dom"; import IndexPage from "./view/index"; import AboutPage from "./view/about"; import Page404 from "./view/Page404"; function App() { return ( <div className="App"> <Switch> <Route path='/' exact component={IndexPage}></Route> <Route path='/about' exact component={AboutPage}></Route> <Page404 component={Page404}></Page404> </Switch> </div> ); } export default App;
In the above case, pay attention to the writing order of page 404. If it is written at the top of the Switch, no matter which page is loaded, only the content of the page flying away will appear, so it should be written at the bottom of the Switch
Redirect component
to property: sets the URL of the jump
<!-- app.js --> import React from 'react'; import { Route, Switch, Redirect } from "react-router-dom"; import IndexPage from "./view/index"; import Page404 from "./view/Page404"; function App() { return ( <div className="App"> <Switch> <Route path='/' exact render={()=>{ return <Redirect to='/list/1'></Redirect> }}></Route> <Route path='/list/:page' exact render={(props)=>{ return <IndexPage {...props} ></IndexPage> }}></Route> <Page404 component={Page404}></Page404> </Switch> </div> ); } export default App;
The purpose of the above case is to make the page load in the page with page=1, and make the above address bar display the same http://localhost:3000/list/1
withRouter component (high-order component, high-order function, high-order routing)
If a component is not a route binding component, there are no route related objects in its props. Although it can be passed in by passing parameters, it will be particularly cumbersome if the structure is complex. Therefore, you can inject routing objects through the withRouter method
<!-- src/view/about.js --> import React from "react"; import Inner from "./inner"; export default function AboutMorePage(props){ let {location,match} = props; // console.log(match); return ( <div> <h1>About us</h1> <Inner /> </div> ) }
<!-- src/view/inner.js --> import React from "react"; import { withRouter } from "react-router-dom"; function Inner(props){ return ( <div> <h1>Inner</h1> <button onClick={()=>{ console.log(props); }}>Button</button> </div> ) } export default withRouter(Inner);
Hooks (after router 5.0)
- Not used within class components
- useHistory: get History object
- useLocation: get Location object
- useParams: get Params
- useRouteMatch: get Match
Summary:
- Routing has its advantages and disadvantages
- React Router provides a routing library for web environment and native environment
- Types of routes: browserouter component and HashRouter component