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>