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

news2024/9/22 17:20:23

目录:

  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身上的API
		let 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"/>
    <meta
            name="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.params
        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;

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.state
        return (
            <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.state
        return (
            <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.params

        const {search} = this.props.location
        const {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.state
        return (
            <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.state
        return (
            <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.state
        return (
            <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可以用于解决一些路径错误相关的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1122238.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Docker从入门到入土 3】Docker镜像的创建方法

Part3 一、Docker镜像1.1 镜像的概念1.2 镜像结构的分层 二、Docker镜像的创建2.1 基于现有镜像创建2.1.1 创建思路2.1.2 举个例子 2.2 基于本地模板创建2.3 基于Dockerfile 创建 三、Dockerfile 详解3.1 Dockerfile 操作指令3.1.1 常用的操作指令3.1.2 CMD和ENTRYPOINT的区别…

【Java基础面试四十一】、说一说你对static关键字的理解

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;说一说你对static关键字…

hdlbits系列verilog解答(异或非门)-08

文章目录 wire线网类型介绍一、问题描述二、verilog源码三、仿真结果 wire线网类型介绍 wire线网类型是verilog的一种数据类型&#xff0c;它是一种单向的物理连线。它可以是输入也可以是输出&#xff0c;它与reg寄存器数据类型不同&#xff0c;它不能存储数据&#xff0c;只能…

文件系统相关

文件系统部分的大纲要求&#xff1a; 文件系统的全局结构&#xff1a;文件系统在外存中的结构&#xff0c;文件系统在内存中的结构外存空闲空间管理办法虚拟文件系统文件系统挂载 一、文件系统的层次结构 可分为三个层次&#xff1a;最低层是对象及其属性&#xff0c;中间层…

物证管理系统|智物证DW-S404是一套成熟系统

系统背景 我司物证智能管理系统&#xff08;智物证DW-S404&#xff09;是一套成熟系统&#xff0c;依托互3D技术、RFID技术、数据库技术、AI、视频分析技术对物证进行统一管理、分析的信息化、智能化、规范化的系统。 物证是公安或者监狱处理案件的关键凭证&#xff0c;针对过…

3交换机的配置与使用

越来越发觉大学的教程是真好&#xff0c;虽然说深度可能不太够&#xff0c;但作为入门实在太好了。中国也有公开课&#xff0c;推荐中国大学MOOC&#xff0c;感谢网易有道与高教社。 最近特别累、活也特别多&#xff0c;所以学习的时间少了很多。但看到MOOC之后&#xff0c;又…

软件测试(六)自动化测试 Junit5

Junit5 selenium是自动化测试框架&#xff08;写自动化测试用例&#xff09;Junit单元测试框架&#xff08;管理写好的测试用例&#xff09; 注解&#xff1a;Test&#xff0c;Disable &#xff0c;BeforeAll&#xff0c;AfterAll&#xff0c;BeforeEach&#xff0c;AfteEach…

操作系统——多个类别产品的生产者-消费者问题(王道视频p33、课本ch6)

1.问题解剖——得到的是 1个“互斥信号量” 3个“同步信号量” 其中特别注意&#xff0c;对于盘子plate可以清空的设计4个对象的&#xff0c;但是只用这一个同步信号量就可以实现 2.代码—— 3.由于这里的同步信号量的初值都是1&#xff0c;所以&#xff0c;即使不设置互斥信…

04.Finetune vs. Prompt

目录 语言模型回顾大模型的两种路线专才通才二者的比较 专才养成记通才养成记Instruction LearningIn-context Learning 自动Prompt 部分截图来自原课程视频《2023李宏毅最新生成式AI教程》&#xff0c;B站自行搜索 语言模型回顾 GPT&#xff1a;文字接龙 How are __. Bert&a…

大语言模型(LLM)综述(二):开发大语言模型的公开可用资源

A Survey of Large Language Models 前言3. RESOURCES OF LLMS3.1 公开可用的模型CheckPoints或 API3.2 常用语料库3.3 库资源 前言 随着人工智能和机器学习领域的迅速发展&#xff0c;语言模型已经从简单的词袋模型&#xff08;Bag-of-Words&#xff09;和N-gram模型演变为更…

RK3568 USB驱动开发

一.USB的DTS配置说明 1.USB 2.0 控制器 DTS 1.1 USB 2.0 Host 控制器 DTS USB 2.0 Host0 控制器 (EHCI & OHCI) 的DTS为例&#xff1a; 其中&#xff0c;EHCI 控制器的 compatible 固定为 “generic-ehci”&#xff0c;OHCI 控制器的 compatible 固定为 “genericohci”…

39.克鲁斯卡尔(Kruskal)算法

一言 已知n个顶点&#xff0c;选n-1条最短的边&#xff0c;不可成环。 概述 克鲁斯卡尔&#xff08;Kruskal&#xff09;算法是用来求加权连通图的最小生成树的算法。其基本思想是按照权值从小到大的顺序选择n-1条边&#xff0c;保证这n-1条边不构成回路。 这就要求要首先构…

写给Java/Android开发者的Python入门教程

1. 前言 对于Java/Android开发工程师来说&#xff0c;已经掌握了Java语言&#xff0c;这时再学其他语言(C/C除外)&#xff0c;都是比较容易的&#xff0c;可能花上几个小时就能入门了。 作为一个Android开发工程师&#xff0c;今天一时兴起&#xff0c;学了下Python&#xff0…

初识进程以及父子进程

一 进程概念 什么是进程呢&#xff1f;许多资料都说一个已经加载到内存的程序就叫进程&#xff0c;意思是只要代码到了内存就能跑起来了吗?接下来我就谈谈对进程概念的理解。 1 如何管理进程 我们可能运行多个进程&#xff0c;这些进程有些结束&#xff0c;有些要退出&#x…

yolov5自己的数据集制作

文章目录 一、制作数据集1、创建文件夹结构如下2、将之前的图片以及标注数据放入mydata文件夹3、新建一个mydata.yaml文件 二、基于数据集训练模型1、基于数据集训练模型2、开始根据制作好的数据集训练模型3、模型训练结束 三、部署模型 文章参考博主&#xff1a;风吹落叶花飘荡…

Power BI 傻瓜入门 6. 从动态数据源获取数据

本章内容将介绍 发现如何从关系数据库和非关系数据库中提取数据学习如何使用Power BI使用在线和实时数据源跨多个数据源应用分析服务使用Power BI通过静态和动态数据解决纠正措施 数据有时可能有点复杂。诚然&#xff0c;上传一个包含几个电子表格的文件&#xff0c;或者一个…

计算机中整数的补码表示及二进制数轮

为了同学们能理好的理解数在计算机内的表示&#xff0c;我们可以把计算机中的整数看成N位进制数的数轮&#xff0c;N一般为2的幂&#xff0c;如下&#xff1a; 我们来举个例子&#xff1a;如果用4位二进制来表示整数&#xff0c;则可以表示的整数范围为-8&#xff08;即&#x…

详细介绍如何使用Ipopt非线性求解器求解带约束的最优化问题

本文中将详细介绍如何使用Ipopt非线性求解器求解带约束的最优化问题&#xff0c;结合给出的带约束的最优化问题示例&#xff0c;给出相应的完整的C程序&#xff0c;并给出详细的解释和注释&#xff0c;以及编译规则等 一、Ipopt库的安装和测试 本部分内容在之前的文章《Ubuntu2…

STM32-LTC6804方案成熟BMS方案

方案下载链接&#xff01;&#xff01;https://mp.weixin.qq.com/s?__bizMzU2OTc4ODA4OA&mid2247549092&idx1&snc73855c4e3d5afddd8608d8528864f95&chksmfcfb1373cb8c9a65a4bd1f545a1a587af882f209e7ccbb8944f4d2514d241ca1d7fcc4615e10&token539106225&a…