依旧十分钟学会在TypeScript使用react路由
一天一个小目标
今日目标:能够在typescript中使用react路由
1、安装路由包
npm i react-router-dom@5.3.0
安装声明文件
因为 react-router-dom这个包没有声明文件也就是.d.ts结尾的文件
npm i @types/react-router-dom
创建页面配置路由
import { BrowserRouter as Router, Link, Route } from 'react-router-dom'
import Home from './pages/Home'
import Login from './pages/Login'
export default function App() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/home">首页</Link>
</li>
<li>
<Link to="/login">登录页</Link>
</li>
</ul>
<div>
<Route path="/home" component={Home}></Route>
<Route path="/login" component={Login}></Route>
</div>
</div>
</Router>
)
}
useHistory的基本使用-页面跳转
useHistory可以用来做路由之间的跳转,并且在跳转时可以指定跳转参数state的类型
useHistory的签名声明如下
export function useHistory<HistoryLocationState = H.LocationState>(): H.History<HistoryLocationState>;
useHistory如果仅仅实现跳转功能,和js中使用语法一致,咱们不用做任何的配置
const history = useHistory()
const login = () => {
history.push('/login')
}
但是很多情况下,我们都需要携带参数,最普遍的就是登录的回跳
useHistory的进阶使用-页面跳转传参
新建页面Home.tsx和Login.tsx
在/Login页面,通过state传递参数
两种方式传的参数一样
const history = useHistory()
// 方式1
history.push('/home', { a:1 })
// 方式2
history.push({pathname: '/home', state:{a:1 }})
如果希望跳转传参时,有指定的格式,可以给useHistory泛型提供类型参数,例如:
const history = useHistory<{a: number }>()
这样,在通过state携带参数时,就会有限制了。
获取参数
在‘/home’页面中,通过useLocation
来获取上一个页面传递的参数。
先看看原来的写法:
import { useLocation } from 'react-router'
const location = useLocation()
const aa = location.state.a // 这里的a就是上一个页面中通过state传进来的
结果肯定会报错,因为他不知道state里有a
此时我们也可以约定他的泛型参数
import { useLocation } from 'react-router'
export default function Home() {
//必须有a,并且是string类型
const location = useLocation<{ a: string }>()
const a = location.state?.a
这种页面传参约定类型,如果是我们自己做传参就没什么问题,但是万一是A同事传给我们的,我俩又没约定好泛型,不就拿不到报错了吧。所以一般我们是新建一个 .d.ts后缀的类型声明文件,然后将home.tsx和login.tsx中的类型提炼出来放在一个单独的文件,这样只需要都导入这个文件,就避免了需要去约定的麻烦!
在type.d.ts的文件下
export type LoginState = { a: string }
然后传参只需要在当前页面导入即可,方便很多!
import { LoginState } from "../types"
export default function Home() {
// 接收从login传入的值
const location = useLocation<LoginState>()
细节处理
从login.tsx跳入home.tsx时会设置state,所以能获取具体的参数
直接访问home.tsx就会报错, 原因是没有传入state
所以我们要允许不传入state
// types.d.ts
export type LoginState = { a: string } | null
useParams的使用
先在跟组件这里写好/:id
<Route path="/home/:id" component={Home}></Route>
<Route path="/login" component={Login}></Route>
通过useParams获取参数
import { useParams } from 'react-router'
export default function Home() {
const params = useParams()
console.log("params.id", params.id) // 这里会报错,因为空对象里面没有id
}
所以我们要指定泛型参数
const params = useParams<{ id: string }>()
console.log(params.id)//这样就不会报错了
路由相关的hook小结
用来接收参数时:useLocation, useParams要补充类型变量
用来传递参数的:useHistory可以不加
转载自:https://juejin.cn/post/7081577520021110820