likes
comments
collection
share

依旧十分钟学会在TypeScript使用react路由

作者站长头像
站长
· 阅读数 30

一天一个小目标

今日目标:能够在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携带参数时,就会有限制了。

依旧十分钟学会在TypeScript使用react路由

获取参数

在‘/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
评论
请登录