携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情
一、react路由中使用ts
输入命令npm i react-router-dom@5
安装路由:
再输入命令:
npm i --save-dev @types/react-router-dom
安装路由类型推断。
新建如下文件:
Film.tsx
写入如下代码:
import axios from 'axios'
import { Component } from 'react'
import { RouteComponentProps } from 'react-router-dom'
interface JItem {
cinemaId: number,
name: string
}
export default class Film extends Component<RouteComponentProps> {
state = {
cinemaList: []
}
componentDidMount() {
axios({
url: 'https://m.maizuo.com/gateway?cityId=110100&ticketFlag=1&k=3085018',
method: 'get',
headers: {
'X-Client-Info':' {"a":"3000","ch":"1002","v":"5.2.0","e":"1646314068530784943341569"}',
'X-Host': 'mall.film-ticket.cinema.list'
}
}).then((res) => {
this.setState({
cinemaList: res.data.data.cinemas
})
}).catch((err) => {
console.log(err)
})
}
render() {
return (
<div>
<ul>
{
this.state.cinemaList.map((item: JItem) =>
<li key={item.cinemaId} onClick={() => {
this.props.history.push(`/cinema/${item.cinemaId}`)
}}>{item.name}</li>
)
}
</ul>
</div>
)
}
}
Cinema.tsx
写入如下代码:
import { Component } from 'react'
import { RouteChildrenProps } from 'react-router-dom'
interface IParams {
cinemaId: string
}
export default class Cinema extends Component<RouteChildrenProps<IParams>> {
componentDidMount() {
console.log((this.props.match?.params as any).cinemaId)
console.log(this.props.match?.params.cinemaId)
}
render() {
return (
<div>Cinema</div>
)
}
}
新建router\router.tsx
,写入代码:
import { Component } from 'react'
import {HashRouter, Route} from 'react-router-dom'
import Center from '../component/Center'
import Cinema from '../component/Cinema'
import Film from '../component/Film'
export default class Router extends Component {
render() {
return (
<HashRouter>
<Route path="/film" component={Film}></Route>
<Route path="/cinema/:cinemaId" component={Cinema}></Route>
<Route path="/center" component={Center}></Route>
</HashRouter>
)
}
}
新建router\index.tsx
,写入代码:
import React, { Component } from 'react'
import store from '../redux/store'
import Router from './router'
export default class Index extends Component {
render() {
return (
<div>
<Router></Router>
</div>
)
}
}
可以看到ts
的写法与普通js
写法多了RouteComponentProps
类型推断,并且自己写的interface JItem
接口去对接cinemaId
,name
类型。
在Cinema.tsx
子组件中,也多了RouteComponentProps
类型推断,并且取路由传参过来的值,第一种方法使用了类型推断。第二种方法是自己写了一个接口去对接类型。这两种方法都可以取到值。
效果:
二、redux中使用ts
新建redux\store.ts
,写入如下代码:
import { createStore } from "redux"
interface IAction {
type: string,
payload?: any
}
interface IState {
isShow: boolean
}
const reducer = (prevState:IState={
isShow: true
},
action: IAction) => {
const {type} = action
const newState = {...prevState}
switch(type) {
case "show":
newState.isShow = true
return newState
case "hide":
newState.isShow = false
return newState
default:
return prevState
}
}
const store = createStore(reducer)
export default store
router\index.tsx
修改为如下代码:
import React, { Component } from 'react'
import store from '../redux/store'
import Router from './router'
export default class Index extends Component {
state = {
isShow: store.getState().isShow
}
componentDidMount() {
store.subscribe(() => {
console.log(store.getState())
this.setState({
isShow: store.getState().isShow
})
})
}
render() {
return (
<div>
<Router></Router>
{
this.state.isShow && <div>显示/隐藏</div>
}
</div>
)
}
}
可以看到在redux
中我们定义了两个接口去限制了state
和action
的类型推断,让我们在写代码的阶段就能够将写错字母的问题给提前发现。效果:
在学习React + Typescript的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。