React学习-router路由
router-hash
- 下载
npm i react-router-dom
- 使用,并引入
import {HashRouter,Link,Route,Switch} from 'react-router-dom'
- 先实现出一个ul-li无序列表做目录
<ul>
<li><Link to="/">首页</Link></li>
<li><Link to="/list">列表页</Link></li>
<li><Link to="/my">我的</Link></li>
</ul>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/list" component={List}/>
<Route path="/my" component={My}/>
</Switch>
这里switch和Route标签配合用于实现需要跳转到的路由所对应的组件
对组件的定义
let Home=()=><div>首页</div>;
let List=()=><div>列表页</div>;
let My=()=><div>我的页面</div>;
这样就可以实现跳转了
- HashRouter 👉 路由的模式,hash模式,包裹整个路由页面
- Route 👉 展示组件
- Link 👉 按钮组件
- Switch 👉 每次只能出现一个
- exact 👉 精确匹配
BrowserRouter
- 我们先定义一个函数组件
function Child(){
let {name} = useParams();
return (
<div>{name}</div>
)
}
这里useParams也需要从react-router-dom中引入
import {BrowserRouter,Link,Route,Switch,useParams} from 'react-router-dom'
useParams表示父组件传过来的参数列表
在父组件中
export default class App extends React.Component{
render(){
return (
<BrowserRouter>
<div>
<ul>
<li><Link to="/aaa">首页</Link></li>
<li><Link to="/bbb">列表页</Link></li>
<li><Link to="/ccc">我的</Link></li>
</ul>
<Switch>
<Route exact path="/:name" children={<Child/>}/>
</Switch>
</div>
</BrowserRouter>
)
}
}
用/:name来传参给Child子组件,传参的内容就是上面路由后的aaa,bbb,ccc这样的参数
先来看看效果
点击不同的选项卡,给子组件中带入到不同的参数
如果需要传递多个参数呢?
只需要继续跟在后面拼接/:param这样的代码即可
<BrowserRouter>
<div>
<ul>
<li><Link to="/aaa/1">首页</Link></li>
<li><Link to="/bbb/2">列表页</Link></li>
<li><Link to="/ccc/3">我的</Link></li>
</ul>
<Switch>
<Route exact path="/:name/:id" children={<Child/>}/>
</Switch>
</div>
</BrowserRouter>
子组件中多接收一个参数即可
let {name,id} = useParams();
看看效果
同时带出两个参数给子组件
- useParams 👉 获取属性传值
路由的嵌套
react-router也支持嵌套,如下面的测试代码
App.js
export default class App extends React.Component{
render(){
return (
<BrowserRouter>
<div>
<ul>
<li><Link to="/home">Home</Link></li>
<li><Link to="/list">List</Link></li>
</ul>
<Switch>
<Route path="/home" children={<Home/>}/>
<Route path="/list">
<List></List>
</Route>
</Switch>
</div>
</BrowserRouter>
)
}
}
function Home(){
return (
<div>我是home组件</div>
)
}
function List(){
return (
<div>
<p>我是list</p>
<ul>
<li><Link to="/list/aaa">aaa</Link></li>
<li><Link to="/list/bbb">bbb</Link></li>
<li><Link to="/list/ccc">ccc</Link></li>
</ul>
<Switch>
<Route path="/list/:name" children={<Child/>}></Route>
</Switch>
</div>
)
}
function Child(){
let {name} = useParams();
return (
<div>
<p>{name}</p>
</div>
)
}
实现的效果
- 当点击Home时
- 当点击List,并选择List中的路由时
useRouteMatch
改造下List这个函数组件的代码,用useRouteMatch去改造。
function List(){
let {path,url} = useRouteMatch();
return (
<div>
<p>我是list</p>
<ul>
<li><Link to={`${url}/aaa`}>aaa</Link></li>
<li><Link to={`${url}/bbb`}>bbb</Link></li>
<li><Link to={`${url}/ccc`}>ccc</Link></li>
</ul>
<Switch>
<Route path={`${path}/:name`} children={<Child/>}></Route>
</Switch>
</div>
)
}
最后实现效果和上面路由嵌套一样
- useRouteMatch 👉 用在path,url,用在to上
useHistory
- 不能把useHistory嵌套在函数内使用
function back(){
let history = useHistory();
history.goBack()
}
像这样
会报错
index.js:1 ./src/App.js
Line 48:17: React Hook "useHistory" is called in function "back" which is neither a React function component or a custom React Hook function react-hooks/rules-of-hooks
Search for the keywords to learn more about each error.
正常来说哪个组件定义就用定义在哪个组件里面
function Child(){
let {name} = useParams();
let history = useHistory();
return (
<div>
<p>{name}</p>
<button onClick={history.goBack}>返回</button>
</div>
)
}
或者
function Child(){
let history = useHistory();
function back(){
history.goBack();
}
let {name} = useParams();
return (
<div>
<p>{name}</p>
<button onClick={back}>返回</button>
</div>
)
}
都可以实现
let history = useHistory();
这段代码一定要定义在顶层,否则就会报错。
来看看实现效果
- 点击前
- 点击后
除此之外还有 - goForward() 👉 前进
- go() 👉 去任何一页
- push() 👉 添加一条历史记录
useLocation
给list带上参数,打印出这个对象
<li><Link to={`${url}/aaa?a=1&b=2`}>aaa</Link></li>
- 控制台输出
可以发现search这个里面装的就是路由后面所带的参数
NavLink
- NavLink是一个高亮的组件
- 现在用NavLink去替换原来的Link,记得要import里面也要带着
<li><NavLink activeClassName="active" to="/home">Home</NavLink></li>
<li><NavLink activeClassName="active" to="/list">List</NavLink></li>
- 新建一个router.css,并引入
.active{
color:red;
}
实现效果
点击哪个标签,那个标签就以红色的形式高亮显示出来
- 也可以写成activeStyle,效果是一样的
<li><NavLink activeStyle={{color:"red"}} to="/home">Home</NavLink></li>
Redirect重定向
当输入值和已有路由不匹配就自动重定向到指定位置
用法
<Route>
<Redirect to="/"></Redirect>
</Route>