当前位置: 首页 > news >正文

[尚硅谷React笔记]——第5章 React 路由

目录:

  1. 对SPA应用的理解
  2. 对路由的理解
  3. 前端路由原理
  4. 路由的基本使用
  5. 路由组件与一般组件
  6. NavLink的使用
  7. 封装NavLink组件
  8. Switch的使用
  9. 解决样式丢失问题
  10. 路由的模糊匹配与严格匹配
  11. Redirect的使用
  12. 嵌套路由
  13. 向路由组件传递params参数
  14. 向路由组件传递search参数
  15. .向路由组件传递state参数
  16. 总结路由参数
  17. push与repalce
  18. 编程式路由导航
  19. withRouter的作用
  20. BrowserRouter与HashRouter

1.对SPA应用的理解

  1. 单页Web应用(single page web application,SPA)。
  2. 整个应用只有一个完整的页面
  3. 点击页面中的链接不会刷新页面,只会做页面的局部更新。
  4. 数据都需要通过ajax请求获取, 并在前端异步展现。

2.对路由的理解 

什么是路由?

  1. 一个路由就是一个映射关系(key:value)
  2. key为路径, value可能是function或component

路由分类

  1. 后端路由:
    1. 理解: value是function, 用来处理客户端提交的请求。
    2. 注册路由: router.get(path, function(req, res))
    3. 工作过程:当node接收到一个请求时, 根据请求路径找到匹配的路由, 调用路由中的函数来处理请求, 返回响应数据
  2. 前端路由:
    1. 浏览器端路由,value是component,用于展示页面内容。
    2. 注册路由: <Route path="/test" component={Test}>
    3. 工作过程:当浏览器的path变为/test时, 当前路由组件就会变为Test组件

3.前端路由原理

前端路由的基石.html 

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>前端路由的基石_history</title>
</head>
<body><a href="http://www.atguigu.com" onclick="return push('/test1') ">push test1</a><br><br><button onClick="push('/test2')">push test2</button><br><br><button onClick="replace('/test3')">replace test3</button><br><br><button onClick="back()">&lt;= 回退</button><button onClick="forword()">前进 =&gt;</button><script type="text/javascript" src="https://cdn.bootcss.com/history/4.7.2/history.js"></script><script type="text/javascript">// let history = History.createBrowserHistory() //方法一,直接使用H5推出的history身上的APIlet history = History.createHashHistory() //方法二,hash值(锚点)function push (path) {history.push(path)return false}function replace (path) {history.replace(path)}function back() {history.goBack()}function forword() {history.goForward()}history.listen((location) => {console.log('请求路由路径变化了', location)})</script>
</body>
</html>

 4.路由的基本使用

  1. 明确好界面中的导航区、展示区
  2. 导航区的a标签改为Link标签 <Link to="/xxxxx" >Demo</Link>
  3. 展示区写Route标签进行路径的匹配<Route path='/xxxx 'component={Demo}/>
  4. <App>的最外侧包裹了一个<BrowserRouter>或<HashRouter>

App.js

import React, {Component} from 'react';
import {Link, Route} from "react-router-dom";
import About from "./components/About/About";
import Home from "./components/Home/Home";class App extends Component {render() {return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><div className="page-header"><h2>React Router Demo</h2></div></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><Link className="list-group-item" to="/about">About</Link><Link className="list-group-item" to="/home">Home</Link></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body"><Route path="/about" component={About}></Route><Route path="/home" component={Home}></Route></div></div></div></div></div>);}
}export default App;

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import {BrowserRouter} from "react-router-dom";const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<BrowserRouter><App/></BrowserRouter>
);

About.jsx

import React, {Component} from 'react';class About extends Component {render() {return (<div><h3>我是About的内容</h3></div>);}
}export default About;

Home.jsx

import React, {Component} from 'react';class Home extends Component {render() {return (<div><h3>我是Home的内容</h3></div>);}
}export default Home;

运行结果:

5.路由组件与一般组件

  1. 写法不同:
    1. 一般组件: <Demo/ >
    2. 路由组件: <Route path="/demo" component={Demo}/>
  2. 存放位置不同:
    1. 一般组件:components
    2. 路由组件: pages
  3. 接收到的props不同:
    1. 一般组件:,写组件标签时传递了什么,就能收到什么
    2. 路由组件:接收到三个固定的属性
      1. history:
         
        1. go: f go(n)
        2. goBack: f goBack()
        3. goForward: f goForward()
        4. push: f push(path,state)
        5. replace: f replace(path, state)
      2. location:

        1. pathname: "/about"
        2. search: ""
        3. state: undefined
      3. match:|

        1. params: {}
        2. path: "/about"
        3. url: "/about"

 6.NavLink的使用

 Header.jsx

import React, {Component} from 'react';class Header extends Component {render() {// console.log('Header组件收到的props是', this.props)return (<div><div className="page-header"><h2>React Router Demo</h2></div></div>);}
}export default Header;

About.jsx

import React, {Component} from 'react';class About extends Component {render() {// console.log('About组件收到的props是', this.props)return (<div><h3>我是About的内容</h3></div>);}
}export default About;

Home.jsx

import React, {Component} from 'react';class Home extends Component {render() {return (<div><h3>我是Home的内容</h3></div>);}
}export default Home;

App.js

import React, {Component} from 'react';
import {NavLink, Route} from "react-router-dom";
import About from "./pages/About/About";
import Home from "./pages/Home/Home";
import Header from "./components/Header/Header";class App extends Component {render() {return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><Header a={1}></Header></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><NavLink activeClassName="atguigu" className="list-group-item" to="/about">About</NavLink><NavLink activeClassName="atguigu" className="list-group-item" to="/home">Home</NavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body"><Route path="/about" component={About}></Route><Route path="/home" component={Home}></Route></div></div></div></div></div>);}
}export default App;

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import {BrowserRouter} from "react-router-dom";const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<BrowserRouter><App/></BrowserRouter>
);

index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"/><link rel="icon" href="%PUBLIC_URL%/favicon.ico"/><meta name="viewport" content="width=device-width, initial-scale=1"/><meta name="theme-color" content="#000000"/><metaname="description"content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png"/><link rel="manifest" href="%PUBLIC_URL%/manifest.json"/><link rel="stylesheet" href="css/bootstrap.css"><style>.atguigu {background-color: orange !important;color: white !important;}</style><title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>

项目结构:

运行结果:

 7.封装NavLink组件

NavLink与封装NavLink

  1. NavLink可以实现路由链接的高亮,通过activeclassName指定样式名
  2. 标签体内容是一个特殊的标签属性
  3. 通过this.props.children可以获取标签体内容

 App.js

import React, {Component} from 'react';
import {NavLink, Route} from "react-router-dom";
import About from "./pages/About/About";
import Home from "./pages/Home/Home";
import Header from "./components/Header/Header";
import MyNavLink from "./components/MyNavLink/MyNavLink";class App extends Component {render() {return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><Header a={1}></Header></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><MyNavLink to="/about" a={1} b={2} c={3}>About</MyNavLink><MyNavLink to="/home">Home</MyNavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body"><Route path="/about" component={About}></Route><Route path="/home" component={Home}></Route></div></div></div></div></div>);}
}export default App;

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import {BrowserRouter} from "react-router-dom";const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<BrowserRouter><App/></BrowserRouter>
);

Header.jsx

import React, {Component} from 'react';class Header extends Component {render() {// console.log('Header组件收到的props是', this.props)return (<div><div className="page-header"><h2>React Router Demo</h2></div></div>);}
}export default Header;

MyNavLink.jsx

import React, {Component} from 'react';
import {NavLink} from "react-router-dom";class MyNavLink extends Component {render() {console.log(this.props)return (<div><NavLink activeClassName="atguigu" className="list-group-item" {...this.props}/></div>);}
}export default MyNavLink;

About.jsx

import React, {Component} from 'react';class About extends Component {render() {// console.log('About组件收到的props是', this.props)return (<div><h3>我是About的内容</h3></div>);}
}export default About;

Home.jsx

import React, {Component} from 'react';class Home extends Component {render() {return (<div><h3>我是Home的内容</h3></div>);}
}export default Home;

项目结构:

运行结果:

 

8.Switch的使用

  1. 通常情况下,path和component是一一对应的关系。
  2. Switch可以提高路由匹配效率(单一匹配)。

Test.jsx

import React, {Component} from 'react';class Test extends Component {render() {return (<div><h2>Test...</h2></div>);}
}export default Test;

App.js

import React, {Component} from 'react';
import {NavLink, Route, Switch} from "react-router-dom";
import About from "./pages/About/About";
import Home from "./pages/Home/Home";
import Header from "./components/Header/Header";
import MyNavLink from "./components/MyNavLink/MyNavLink";
import Test from "./pages/Test/Test";class App extends Component {render() {return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><Header a={1}></Header></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><MyNavLink to="/about" a={1} b={2} c={3}>About</MyNavLink><MyNavLink to="/home">Home</MyNavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body"><Switch><Route path="/about" component={About}></Route><Route path="/home" component={Home}></Route><Route path="/home" component={Test}></Route></Switch></div></div></div></div></div>);}
}export default App;

运行结果:

项目结构:

9.解决样式丢失问题 

  1. public/index.html 中引入样式时不写./写/(常用)

  2. public/index.html 中引入样式时不写﹒/写%PUBLIC_URL%(常用)

  3. 使用HashRouter

1../css/bootstrap.css改为:

<link rel="stylesheet" href="css/bootstrap.css">

2../css/bootstrap.css改为:

<link rel="stylesheet" href="%PUBLIC_URL%/css/bootstrap.css">

3.BroserRouter改成HashRouter

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import {BrowserRouter, HashRouter} from "react-router-dom";const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<HashRouter><App/></HashRouter>
);

 10.路由的模糊匹配与严格匹配

  1. 默认使用的是模糊匹配(简单记:【输入的路径】必须包含要【匹配的路径】,且顺序要一致)
  2. 开启严格匹配:<Route exact={true} path="/about" component={About}/>
  3. 严格匹配不要随便开启,需要再开,有些时候开启会导致无法继续匹配二级路由

 App.js

import React, {Component} from 'react';
import {Route, Switch} from "react-router-dom";
import About from "./pages/About/About";
import Home from "./pages/Home/Home";
import Header from "./components/Header/Header";
import MyNavLink from "./components/MyNavLink/MyNavLink";class App extends Component {render() {return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><Header a={1}></Header></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><MyNavLink to="/about">About</MyNavLink><MyNavLink to="/home/a/b">Home</MyNavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body"><Switch><Route exact path="/about" component={About}></Route><Route exact path="/home" component={Home}></Route></Switch></div></div></div></div></div>);}
}export default App;

运行结果:

11.Redirect的使用

  1. 一般写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由
  2. 具体编码:
    <Switch>
    <Route path="/about" component={About}/>
    <Route path="/home" component={Home}/>
    <Redirect to="/about"/>
    </Switch>

App.js

import React, {Component} from 'react';
import {Redirect, Route, Switch} from "react-router-dom";
import About from "./pages/About/About";
import Home from "./pages/Home/Home";
import Header from "./components/Header/Header";
import MyNavLink from "./components/MyNavLink/MyNavLink";class App extends Component {render() {return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><Header a={1}></Header></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><MyNavLink to="/about">About</MyNavLink><MyNavLink to="/home">Home</MyNavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body"><Switch><Route path="/about" component={About}></Route><Route path="/home" component={Home}></Route><Redirect to="/about"></Redirect></Switch></div></div></div></div></div>);}
}export default App;

12.嵌套路由

  1. 注册子路由时要写上父路由的path值
  2. 路由的匹配是按照注册路由的顺序进行的

App.js

import React, {Component} from 'react';
import {Redirect, Route, Switch} from "react-router-dom";
import About from "./pages/About/About";
import Home from "./pages/Home/Home";
import Header from "./components/Header/Header";
import MyNavLink from "./components/MyNavLink/MyNavLink";class App extends Component {render() {return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><Header a={1}></Header></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><MyNavLink to="/about">About</MyNavLink><MyNavLink to="/home">Home</MyNavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body"><Switch><Route path="/about" component={About}></Route><Route path="/home" component={Home}></Route><Redirect to="/about"></Redirect></Switch></div></div></div></div></div>);}
}export default App;

Message.jsx

import React, {Component} from 'react';class Message extends Component {render() {return (<div><ul><li><a href="/message1">message001</a>&nbsp;&nbsp;</li><li><a href="/message2">message002</a>&nbsp;&nbsp;</li><li><a href="/message/3">message003</a>&nbsp;&nbsp;</li></ul></div>);}
}export default Message;

 News.jsx

import React, {Component} from 'react';class News extends Component {render() {return (<div><ul><li>news001</li><li>news002</li><li>news003</li></ul></div>);}
}export default News;

Home.jsx

import React, {Component} from 'react';
import MyNavLink from "../../components/MyNavLink/MyNavLink";
import {Redirect, Route, Switch} from "react-router-dom";
import News from "./News/News";
import Message from "./Message/Message";class Home extends Component {render() {return (<div><h2>Home组件内容</h2><div><ul className="nav nav-tabs"><li><MyNavLink to="/home/news">News</MyNavLink></li><li><MyNavLink to="/home/message">Message</MyNavLink></li></ul><Switch><Route path="/home/news" component={News}></Route><Route path="/home/message" component={Message}></Route><Redirect to="/home/news"></Redirect></Switch></div></div>);}
}export default Home;

MyNavLink.jsx

import React, {Component} from 'react';
import {NavLink} from "react-router-dom";class MyNavLink extends Component {render() {console.log(this.props)return (<div><NavLink activeClassName="atguigu" className="list-group-item" {...this.props}/></div>);}
}export default MyNavLink;

Header.jsx

import React, {Component} from 'react';class Header extends Component {render() {// console.log('Header组件收到的props是', this.props)return (<div><div className="page-header"><h2>React Router Demo</h2></div></div>);}
}export default Header;

About.jsx

import React, {Component} from 'react';class About extends Component {render() {// console.log('About组件收到的props是', this.props)return (<div><h3>我是About的内容</h3></div>);}
}export default About;

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import {BrowserRouter, HashRouter} from "react-router-dom";const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<HashRouter><App/></HashRouter>
);

项目结构:

运行结果:

13. 向路由组件传递params参数

1.params参数

  • 路由链接(携带参数):<Link to='/demo/test/tom/18'}>详情</Link>
  • 注册路由(声明接收):<Route path="/demo/test/:name/:age" component={Test}/>
  • 接收参数: const {id,title} = this.props.match.params 

Header.jsx

import React, {Component} from 'react';class Header extends Component {render() {// console.log('Header组件收到的props是', this.props)return (<div><div className="page-header"><h2>React Router Demo</h2></div></div>);}
}export default Header;

MyNavLink.jsx

import React, {Component} from 'react';
import {NavLink} from "react-router-dom";class MyNavLink extends Component {render() {console.log(this.props)return (<div><NavLink activeClassName="atguigu" className="list-group-item" {...this.props}/></div>);}
}export default MyNavLink;

About.jsx

import React, {Component} from 'react';class About extends Component {render() {// console.log('About组件收到的props是', this.props)return (<div><h3>我是About的内容</h3></div>);}
}export default About;

Detail.jsx

import React, {Component} from 'react';const DetailData = [{id: '01', content: '你好,中国'},{id: '02', content: '你好,尚硅谷'},{id: '03', content: '你好,未来的自己'},
]class Detail extends Component {render() {// console.log(this.props)const {id, title} = this.props.match.paramsconst findResult = DetailData.find((detailObj) => {return detailObj.id === id})return (<ul><li>ID:{id}</li><li>TITLE:{title}</li><li>CONTENT:{findResult.content}</li></ul>);}
}export default Detail;

Message.jsx

import React, {Component} from 'react';
import Detail from "./Detail/Detail";
import {Link, Route} from "react-router-dom";class Message extends Component {state = {messageArr: [{id: '01', title: '消息1'},{id: '02', title: '消息2'},{id: '03', title: '消息3'},]}render() {const {messageArr} = this.statereturn (<div><ul>{messageArr.map((msgObj) => {return (<li key={msgObj.id}><Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link></li>)})}</ul><hr></hr><Route path="/home/message/detail/:id/:title" component={Detail}></Route></div>);}
}export default Message;

News.jsx

import React, {Component} from 'react';class News extends Component {render() {return (<div><ul><li>news001</li><li>news002</li><li>news003</li></ul></div>);}
}export default News;

Home.jsx 

import React, {Component} from 'react';
import MyNavLink from "../../components/MyNavLink/MyNavLink";
import {Redirect, Route, Switch} from "react-router-dom";
import News from "./News/News";
import Message from "./Message/Message";class Home extends Component {render() {return (<div><h2>Home组件内容</h2><div><ul className="nav nav-tabs"><li><MyNavLink to="/home/news">News</MyNavLink></li><li><MyNavLink to="/home/message">Message</MyNavLink></li></ul><Switch><Route path="/home/news" component={News}></Route><Route path="/home/message" component={Message}></Route><Redirect to="/home/news"></Redirect></Switch></div></div>);}
}export default Home;

App.js

import React, {Component} from 'react';
import {Redirect, Route, Switch} from "react-router-dom";
import About from "./pages/About/About";
import Home from "./pages/Home/Home";
import Header from "./components/Header/Header";
import MyNavLink from "./components/MyNavLink/MyNavLink";class App extends Component {render() {return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><Header a={1}></Header></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><MyNavLink to="/about">About</MyNavLink><MyNavLink to="/home">Home</MyNavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body"><Switch><Route path="/about" component={About}></Route><Route path="/home" component={Home}></Route><Redirect to="/about"></Redirect></Switch></div></div></div></div></div>);}
}export default App;

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import {BrowserRouter, HashRouter} from "react-router-dom";const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<HashRouter><App/></HashRouter>
);

运行结果:

项目结构:

 

14.向路由组件传递search参数

2.search参数

  • 路由链接(携带参数): <Link to=' /demo/test?name=tom&age=18'}>详情</Link>
  • 注册路由(无需声明,正常注册即可): <Route path="/demo/test" component={Test}/>
  • 接收参数: const isearch} = this.props.location
  • 备注:获取到的search是urlencoded编码字符串,需要借助querystring解析

Message.jsx

import React, {Component} from 'react';
import Detail from "./Detail/Detail";
import {Link, Route} from "react-router-dom";class Message extends Component {state = {messageArr: [{id: '01', title: '消息1'},{id: '02', title: '消息2'},{id: '03', title: '消息3'},]}render() {const {messageArr} = this.statereturn (<div><ul>{messageArr.map((msgObj) => {return (<li key={msgObj.id}>{/*<Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link>*/}<Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link></li>)})}</ul><hr></hr>{/*<Route path="/home/message/detail/:id/:title" component={Detail}></Route>*/}<Route path="/home/message/detail" component={Detail}></Route></div>);}
}export default Message;

Detail.jsx

import React, {Component} from 'react';
import qs from "qs"const DetailData = [{id: '01', content: '你好,中国'},{id: '02', content: '你好,尚硅谷'},{id: '03', content: '你好,未来的自己'},
]class Detail extends Component {render() {console.log(this.props)// const {id, title} = this.props.match.paramsconst {search} = this.props.locationconst {id, title} = qs.parse(search.slice(1))const findResult = DetailData.find((detailObj) => {return detailObj.id === id})return (<ul><li>ID:{id}</li><li>TITLE:{title}</li><li>CONTENT:{findResult.content}</li></ul>);}
}export default Detail;

运行结果:

项目结构:

15.向路由组件传递state参数

state参数:

  • 路由链接(携带参数): <Link to={{path:' /demo/test',state:{name : ' tom' ,age:18]}}>详情</Link>注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
  • 接收参数: this.props.location.state
  • 备注:刷新也可以保留住参数

 Message.jsx

import React, {Component} from 'react';
import Detail from "./Detail/Detail";
import {Link, Route} from "react-router-dom";class Message extends Component {state = {messageArr: [{id: '01', title: '消息1'},{id: '02', title: '消息2'},{id: '03', title: '消息3'},]}render() {const {messageArr} = this.statereturn (<div><ul>{messageArr.map((msgObj) => {return (<li key={msgObj.id}>{/*<Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link>*/}{/*<Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link>*/}<Link to={{pathname: '/home/message/detail',state: {id: msgObj.id, title: msgObj.title}}}>{msgObj.title}</Link></li>)})}</ul><hr></hr>{/*<Route path="/home/message/detail/:id/:title" component={Detail}></Route>*/}{/*<Route path="/home/message/detail" component={Detail}></Route>*/}<Route path="/home/message/detail" component={Detail}></Route></div>);}
}export default Message;

Detail.jsx

import React, {Component} from 'react';
import qs from "qs"const DetailData = [{id: '01', content: '你好,中国'},{id: '02', content: '你好,尚硅谷'},{id: '03', content: '你好,未来的自己'},
]class Detail extends Component {render() {console.log(this.props)// const {id, title} = this.props.match.params// const {search} = this.props.location// const {id, title} = qs.parse(search.slice(1))const {id, title} = this.props.location.state || {}const findResult = DetailData.find((detailObj) => {return detailObj.id === id}) || {}return (<ul><li>ID:{id}</li><li>TITLE:{title}</li><li>CONTENT:{findResult.content}</li></ul>);}
}export default Detail;

运行结果:

16.总结路由参数

17.push与repalce 

Message.jsx

import React, {Component} from 'react';
import Detail from "./Detail/Detail";
import {Link, Route} from "react-router-dom";class Message extends Component {state = {messageArr: [{id: '01', title: '消息1'},{id: '02', title: '消息2'},{id: '03', title: '消息3'},]}render() {const {messageArr} = this.statereturn (<div><ul>{messageArr.map((msgObj) => {return (<li key={msgObj.id}>{/*<Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link>*/}{/*<Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link>*/}<Link replace={true} to={{pathname: '/home/message/detail',state: {id: msgObj.id, title: msgObj.title}}}>{msgObj.title}</Link></li>)})}</ul><hr></hr>{/*<Route path="/home/message/detail/:id/:title" component={Detail}></Route>*/}{/*<Route path="/home/message/detail" component={Detail}></Route>*/}<Route path="/home/message/detail" component={Detail}></Route></div>);}
}export default Message;
  • push:留下记录
  • repalce:不留记录

18.编程式路由导航 

Message.jsx

import React, {Component} from 'react';
import Detail from "./Detail/Detail";
import {Link, Route} from "react-router-dom";class Message extends Component {state = {messageArr: [{id: '01', title: '消息1'},{id: '02', title: '消息2'},{id: '03', title: '消息3'},]}render() {const {messageArr} = this.statereturn (<div><ul>{messageArr.map((msgObj) => {return (<li key={msgObj.id}>{/*<Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link>*/}{/*<Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link>*/}<Link replace={true} to={{pathname: '/home/message/detail',state: {id: msgObj.id, title: msgObj.title}}}>{msgObj.title}</Link></li>)})}</ul><hr></hr>{/*<Route path="/home/message/detail/:id/:title" component={Detail}></Route>*/}{/*<Route path="/home/message/detail" component={Detail}></Route>*/}<Route path="/home/message/detail" component={Detail}></Route></div>);}
}export default Message;

 Detail.jsx

import React, {Component} from 'react';
import qs from "qs"const DetailData = [{id: '01', content: '你好,中国'},{id: '02', content: '你好,尚硅谷'},{id: '03', content: '你好,未来的自己'},
]class Detail extends Component {render() {console.log(this.props)// const {id, title} = this.props.match.params// const {search} = this.props.location// const {id, title} = qs.parse(search.slice(1))const {id, title} = this.props.location.state || {}const findResult = DetailData.find((detailObj) => {return detailObj.id === id}) || {}return (<ul><li>ID:{id}</li><li>TITLE:{title}</li><li>CONTENT:{findResult.content}</li></ul>);}
}export default Detail;

 19.withRouter的作用

News.jsx

import React, {Component} from 'react';class News extends Component {componentDidMount() {setTimeout(() => {this.props.history.push('/home/message')}, 2000)}render() {return (<div><ul><li>news001</li><li>news002</li><li>news003</li></ul></div>);}
}export default News;
  • 借助this.prosp.history对象上的API对操作路由跳转、前进、后退
  • this.prosp.history.push()
  • this.prosp.history.replace()
  • this.prosp.history.goBack()
  • this.prosp.history.goForward()
  • this.prosp.history.go()

 

  1. withRouter可以加工一般组件,让一般组件具备路由组件所特有的API
  2. withRouter的返回值是一个新组件 

Header.jsx

import React, {Component} from 'react';
import {withRouter} from "react-router-dom";class Header extends Component {back = () => {this.props.history.goBack()}forward = () => {this.props.history.goForward()}go = () => {this.props.history.go(2)}render() {// console.log('Header组件收到的props是', this.props)return (<div><div className="page-header"><h2>React Router Demo</h2><button onClick={this.back}>回退</button><button onClick={this.forward}>前进</button><button onClick={this.go}>go</button></div></div>);}
}export default withRouter(Header);

20.BrowserRouter与HashRouter

  • 1.底层原理不一样:
    • BrowserRouter使用的是H5的history API,不兼容IE9及以下版本。
    • HashRouter使用的是URL的哈希值
  • 2.path表现形式不一样
    • BrowserRouter的路径中没有#,例如: localhost:3000/demo/test
    • HashRouter的路径包含#,例如: localhost:3000/#/demo/test
  • 3.刷新后对路由state参数的影响
    • (1).BrowserRouter没有任何影响,因为state保存在history对象中。
    • (2).HashRouter刷新后会导致路由state参数的丢失。
  • 4.备注: HashRouter可以用于解决一些路径错误相关的问题。

相关文章:

[尚硅谷React笔记]——第5章 React 路由

目录&#xff1a; 对SPA应用的理解对路由的理解前端路由原理路由的基本使用路由组件与一般组件NavLink的使用封装NavLink组件Switch的使用解决样式丢失问题路由的模糊匹配与严格匹配Redirect的使用嵌套路由向路由组件传递params参数向路由组件传递search参数.向路由组件传递st…...

如何去掉不够优雅的IF-ELSE

不够优雅的IF-ELSE&#xff1a; 在一个方法中根据两个参数的不同值组合来返回四种可能的类型&#xff0c;你可以使用条件语句&#xff0c;例如 if-else 语句或 switch 语句&#xff0c;来实现这个逻辑。以下是一个示例&#xff0c;假设你有两个参数 param1 和 param2&#xff…...

Python中defaultdict的使用

文章目录 Python 中的 defaultdict 与 dictPython 中的 defaultdict Python 中 defaultdict 的有用函数Python 中的 defaultdict.clear()Python 中的 defaultdict.copy()Python 中的 defaultdict.default_factory()Python 中的 defaultdict.get(key, default value) 今天的文章…...

【ccc3.8】虚拟列表

一个简单的虚拟列表&#xff0c;没有任何其他东西。 原理就是向上滚动时&#xff0c;将下面离开屏幕的那一个item塞到上侧来&#xff1a; 主代码仅有两个&#xff1a;ScrollList对应的滚动容器&#xff0c;ScrollListItem对应单项的预制体 当前支持两种&#xff1a;竖向滚动、…...

【23种设计模式】单一职责原则

个人主页&#xff1a;金鳞踏雨 个人简介&#xff1a;大家好&#xff0c;我是金鳞&#xff0c;一个初出茅庐的Java小白 目前状况&#xff1a;22届普通本科毕业生&#xff0c;几经波折了&#xff0c;现在任职于一家国内大型知名日化公司&#xff0c;从事Java开发工作 我的博客&am…...

DNS入门学习:什么是TTL值?如何设置合适的TTL值?

TTL值是域名解析中的一个重要参数&#xff0c;TTL值设置的合理与否对于域名解析的效率和准确性有着非常重要的影响&#xff0c;因此对于网站管理者而言&#xff0c;了解什么是TTL值以及如何设置合理的TTL值对于做好域名解析管理&#xff0c;确保网站的安全稳定运行至关重要。 …...

ilr normalize isometric log-ratio transformation

visium_heart/st_snRNAseq/05_colocalization/create_niches_ct.R at 5b30c7e497e06688a8448afd8d069d2fa70ebcd2 saezlab/visium_heart (github.com) 更多内容&#xff0c;关注微信&#xff1a;生信小博士 The ILR (Isometric Log-Ratio) transformation is used in the anal…...

el表单的简单查询方法

预期效果 实现表单页面根据groupid 、type 、errortype进行数据过滤 实现 第一步&#xff0c;在页面中添加输入或者是下拉框&#xff0c;并且用相应的v-model进行绑定 <div style"display: flex;flex-direction: row;"><el-input style"width: auto…...

【USRP】通信总的分支有哪些

概述 通信是一个广泛的领域&#xff0c;涵盖了许多不同的技术、应用和专业分支。以下是通信领域的一些主要分支&#xff1a; 有线通信&#xff1a;这涉及到利用物理媒介&#xff08;如电缆、光纤&#xff09;进行通信。 电信&#xff1a;包括电话、电报和传真服务。宽带&#…...

关于服务器网络代理解决方案(1024)

方法一、nginx代理 配置代理服务器 在能够访问外网的服务器上&#xff0c;安装和配置 Nginx。你可以使用包管理器来安装 Nginx&#xff0c;例如&#xff1a; csharpCopy codesudo apt-get install nginx # 对于基于 Debian/Ubuntu 的系统 sudo yum install nginx # 对于基于 C…...

Linux下 /etc/shadow内容详解

/etc/shadow 文件&#xff0c;用于存储 Linux 系统中用户的密码信息&#xff0c;又称为“影子文件”。 前面介绍了 /etc/passwd 文件&#xff0c;由于该文件允许所有用户读取&#xff0c;易导致用户密码泄露&#xff0c;因此 Linux 系统将用户的密码信息从 /etc/passwd 文件中…...

Go学习第二章——变量与数据类型

Go变量与数据类型 1 变量1.1 变量概念1.2 变量的使用步骤1.3 变量的注意事项1.4 ""的使用 2 数据类型介绍3 整数类型3.1 有符号整数类型3.2 无符号整数类型3.3 其他整数类型3.4 整型的使用细节 4 小数类型/浮点型4.1 浮点型的分类4.2 简单使用 5 字符类型5.1 字符类型…...

【剑指Offer】:循环有序列表的插入(涉及链表的知识)

给定循环单调非递减列表中的一个点&#xff0c;写一个函数向这个列表中插入一个新元素 insertVal &#xff0c;使这个列表仍然是循环升序的 给定的可以是这个列表中任意一个顶点的指针&#xff0c;并不一定是这个列表中最小元素的指针 如果有多个满足条件的插入位置&#xff0c…...

【Django 04】Django-DRF(ModelViewSet)

DRF是什么&#xff1f; ModelViewSet 是 Django REST framework 提供的一个视图集类&#xff0c;它封装了常见的模型操作方法。 模型类提供了默认的增删改查功能。 它继承自 GenericViewSet、ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、Dest…...

ubuntu命令

一、 防火墙命令 1、安装防火墙 sudo sudo apt-get install ufw2、查看防火墙状态 sudo ufw status# 返回结果 # Status: inactive # 表示没有开启防火墙3、开启防火墙 sudo ufw enable# 返回结果 # Command may disrupt existing ssh connections. Proceed with operation…...

C++学习之强制类型转换

强制类型转换运算符 带着三个疑问阅读&#xff1a; 出现的背景是什么&#xff1f;何时使用&#xff1f;如何使用&#xff1f; MSDN . 强制转换运算符 C中的四种强制类型转换符详解 static_cast (1) 使用场景 在基本数据类型之间转换&#xff0c;如把 int 转换为 char&#…...

在Linux中,可以使用以下命令来查看进程

在Linux中&#xff0c;可以使用以下命令来查看进程&#xff1a; ps 命令&#xff1a;显示当前用户的进程状态。 ps&#xff1a;显示当前终端会话中正在运行的进程。ps aux&#xff1a;显示系统中所有正在运行的进程&#xff0c;包括其他用户的进程。ps -ef&#xff1a;显示系统…...

【算法训练-动态规划 一】【应用DP问题】零钱兑换、爬楼梯、买卖股票的最佳时机I、打家劫舍

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是【动态规划】&#xff0c;使用【数组】这个基本的数据结构来实现&#xff0c;这个高频题的站点是&#xff1a;CodeTop&#xff0c;筛选条件为&…...

2023年中职组“网络安全”赛项云南省竞赛任务书

2023年中职组“网络安全”赛项 云南省竞赛任务书 一、竞赛时间 总计&#xff1a;360分钟 竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 A模块 A-1 登录安全加固 180分钟 200分 A-2 本地安全策略配置 A-3 流量完整性保护 A-4 事件监控 A-5 服务加固…...

Modeling Deep Learning Accelerator Enabled GPUs

Modeling Deep Learning Accelerator Enabled GPUs 发表在 ISPASS 2019 上。文章研究了 NVIDIA 的 Volta 和 Turing 架构中张量核的设计&#xff0c;并提出了 Volta 中张量核的架构模型。 基于 GPGPU-Sim 实现该模型&#xff0c;并且支持 CUTLASS 运行。发现其性能与硬件非常吻…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...