示例
about页面,有new和message切换菜单,message展示消息列表,点击消息展示message详情
项目层级
这个每一篇博客都不厌其烦的写,其实这个是需要养成一个好习惯,拿起来就可以按固定格式去写,这样才能培养自己的框架思维。
src
components
Header
index.jsx
index.css
MyNavLink
index.jsx
index.css
pages
About
Message
Detail
index.jsx
index.css
index.jsx
index.css
New
index.jsx
index.css
index.jsx
index.css
Home
index.jsx
index.css
App.jsx
App.css
index.css
index.js
方法一:params
App
import React, {Component} from 'react';
import MyNavLink from "./components/MyNavLink";
import {Redirect, Route, Switch} from "react-router-dom";
import Home from "./pages/Home";
import About from "./pages/About";
import './App.css'
class App extends Component {
render() {
return (
<div>
<MyNavLink to="/home">Home</MyNavLink>
<MyNavLink to="/about">About</MyNavLink>
<Switch>
<Route path="/home" component={Home}/>
<Route path="/about" component={About}/>
<Redirect to="/home"/>
</Switch>
</div>
);
}
}
export default App;
Header
import React, {Component} from 'react';
class Header extends Component {
render() {
return (
<div>
<h3>Hello react-router-dom</h3>
</div>
);
}
}
export default Header;
MyNavLink
import React, {Component} from 'react';
import {NavLink} from "react-router-dom";
class MyNavLink extends Component {
render() {
return (
<NavLink {...this.props}/>
);
}
}
export default MyNavLink;
Home
import React, {Component} from 'react';
class Home extends Component {
render() {
return (
<div>
<h3>this is Home Page</h3>
</div>
);
}
}
export default Home;
About
import React, {Component} from 'react';
import MyNavLink from "../../components/MyNavLink";
import {Switch, Route} from 'react-router-dom'
import New from "./New";
import Message from "./Message";
class About extends Component {
render() {
return (
<div>
<h3>this is about page</h3>
<MyNavLink to="/about/new">News</MyNavLink>
<MyNavLink to="/about/message">Messages</MyNavLink>
<Switch>
<Route path="/about/new" component={New}/>
<Route path="/about/message" component={Message}/>
</Switch>
</div>
);
}
}
export default About;
New
import React, {Component} from 'react';
class New extends Component {
render() {
return (
<ul>
<li>react</li>
<li>vue</li>
<li>flask</li>
</ul>
);
}
}
export default New;
Message
import React, {Component} from 'react';
import MyNavLink from "../../../components/MyNavLink";
import {Route, Switch} from "react-router-dom";
import Detail from "./Detail";
class Message extends Component {
state = {
status: 1, total: 3, data: [
{id: '001', name: 'react', detail: '太难了,啥时候是个头呀'},
{id: '002', name: 'flask', detail: '要用啥学啥'},
{id: '003', name: '测试平台', detail: '出师标志'},
]
}
render() {
const {data} = this.state;
return (
<div>
{data.map((messageObj) => {
return (
<li key={messageObj.id}>
<MyNavLink
to={`/about/message/detail/${messageObj.id}/${messageObj.name}/${messageObj.detail}`}>{messageObj.name}
</MyNavLink>
</li>
)
})}
<Switch>
<Route path={`/about/message/detail/:id/:name/:detail`} component={Detail}/>
</Switch>
</div>
);
}
}
export default Message;
Detail
import React, {Component} from 'react';
class Detail extends Component {
render() {
const {id, name, detail} = this.props.match.params;
return (
<ul>
<li>ID:{id}</li>
<li>Title:{name}</li>
<li>Detail:{detail}</li>
</ul>
);
}
}
export default Detail;
总结:
- Route组件,有三个属性,history、location和match,其中params是在match里面的params
- params可以理解为路径
- path中通过/:key_0/:key_1/...来获取传递过来的value
方法一已经将所有代码都已经写了,后面方法只写不同的代码
方法二:search
Message
import React, {Component} from 'react';
import MyNavLink from "../../../components/MyNavLink";
import {Link, Route, Switch} from "react-router-dom";
import Detail from "./Detail";
class Message extends Component {
state = {
status: 1, total: 3, data: [
{id: '001', name: 'react', detail: '太难了,啥时候是个头呀'},
{id: '002', name: 'flask', detail: '要用啥学啥'},
{id: '003', name: '测试平台', detail: '出师标志'},
]
}
render() {
const {data} = this.state;
return (
<div>
{data.map((messageObj) => {
return (
<li key={messageObj.id}>
<Link
to={`/about/message/detail?id=${messageObj.id}&name=${messageObj.name}&detail=${messageObj.detail}`}>{messageObj.name}
</Link>
</li>
)
})}
<Switch>
<Route path="/about/message/detail" component={Detail}/>
</Switch>
</div>
);
}
}
export default Message;
Detail
import React, {Component} from 'react';
import querystring from 'querystring'
class Detail extends Component {
render() {
const {search} = this.props.location;
const {id, name, detail} = querystring.parse(search.slice(1));
return (
<ul>
<li>ID:{id}</li>
<li>Title:{name}</li>
<li>Detail:{detail}</li>
</ul>
);
}
}
export default Detail;
总结:
- search存放在loaction下
- search是路径传的怎样的字符串接收就是怎样的字符串
- 通过querystring进行转换为object
方法三:state
Message
import React, {Component} from 'react';
import {Link, Route, Switch} from "react-router-dom";
import Detail from "./Detail";
class Message extends Component {
state = {
status: 1, total: 3, data: [
{id: '001', name: 'react', detail: '太难了,啥时候是个头呀'},
{id: '002', name: 'flask', detail: '要用啥学啥'},
{id: '003', name: '测试平台', detail: '出师标志'},
]
}
render() {
const {data} = this.state;
return (
<div>
{data.map((messageObj) => {
return (
<li key={messageObj.id}>
<Link
to={{pathname: '/about/message/detail', state: {...messageObj}}}>{messageObj.name}
</Link>
</li>
)
})}
<Switch>
<Route path="/about/message/detail" component={Detail}/>
</Switch>
</div>
);
}
}
export default Message;
Detail
import React, {Component} from 'react';
class Detail extends Component {
render() {
const {id, name, detail} = this.props.location.state || {};
return (
<ul>
<li>ID:{id}</li>
<li>Title:{name}</li>
<li>Detail:{detail}</li>
</ul>
);
}
}
export default Detail;
总结:
- state是放在location下
- 第一次加载的时候state是undefined,所以需要给一个默认空对象
- 注意观察,这个路由的时候,url后面没有跟参数
对比
- params是直接更改了路径,search虽然也是在路径后面加了参数,但是用问号隔开的,不属于路径。所以只有params这个方法更改了路径。更改了路径,路由才能分别识别这些Link,另外两个方法的路径一致,路由无法识别的。所以如果需要区分样式,只能使用params这个方法
- state不会在url增加数据信息,如果涉及到敏感信息,这个方法是一个解决方案。但其实实际工作中大多数情况下会采用加密的方式来解决敏感信息暴露的问题。但state这个方法也提供了一套解决方案
- search需要自己去解析传过来的数据