react-ts

文章目录

react 的类型声明

ts react 难就难在中间件的类型推导, ts 中 react 难度如果为 1,那么 redux 为 5, redux 中间件为 20.

ts 中的类型大部分在库里都已经写好了,但比较难记,这里记录一下。

  1. CSSProperties、MouseEvent
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import React, { CSSProperties } from 'react'

const style: CSSProperties = {
color: 'red',
transition: '.2s'
}

// react 自带 DOM 类型(全局的),或者去 ts.config.js 配置 "lib": ["dom"]
const clickHandle = (event: React.MouseEvent<HTMLULListElement>) => { // 表示绑定事件的是 ul 元素,即 event.currentTarget,event.currentTarget 是事件绑定的元素
let target: HTMLLIElement = event.target as HTMLLIElement // 因为实际点击的是 li,是真正的事件源
const category = target.dataset.category // 自定义属性
}
<ul onClick={clickHandle}>
<li data-category="1">1</li>
<li data-category="2">2</li>
</ul>
  1. PropsChildren
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { PropsWithChildren } from 'react'

// PropsWithChildren 实际上相当于 type PropsWithChildren<T> = T & { children?: ReactNode | undefined }
// ReactNode 实际上相当于 type ReactNode = null | undefined | string | ReactElement
/*
源码 type ReactNode = ReactChild | boolean | null | undefined | ... 还有两个类型 protial
type ReactChild = ReactElement | ReactText
type ReactText = string | number
type ReactElement<P = any, T extends string> = ... 这个比较复杂,直接看源码把
*/

type Props = PropsWithChildren<{
history: History
}>

export defaulut function (props: Props) {
return (
<div>
</div>
)
}
  1. axios
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import { AxiosError } from 'axios'
import { Button, Descriptions, Alert, message } from 'antd'
type StateProps = ReturnType<typeof mapStateToProps>
type Dispatch = typeof actions
interface Params {}
type Props = PropsWithChildren<RouteComponentProps<Params> & StateProps & DispatchProps>
function Profile(props: Props) {
useEffect(() => {
props.validate().catch((err: AxiosError) => message.error('登录失败'))
}, [])
let content
if (props.loginState === LOGIN_TYPES.UNLOGIN) {
content = null
} else if (props.loginState === LOGIN_TYPES.LOGINED) {
content = (
<div>
<Descriptions title="当前用户">
<Descriptions.Item label="姓名">名称</Descriptions.Item>
<Descriptions.Item label="手机号">15xxxxxx</Descriptions.Item>
</Descriptions>
userInfo
</div>
)
} else {
content = (
<>
<Alert type="warning" message="未登录" description="选择注册或登录">
未登录
</Alert>
<Button type="dashed" onClicked={() => {}}>登录</Button>
<Button type="dashed">注册</Button>
</>
)
}
return (
<section>
<NavHeader history={props.history}>个人中心</NavHeader>
{content}
</section>
)
}
  1. redux
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { AnyAction } from 'redux'
enum LOGIN_TYPES {
UN_VALIDATE,
LOGINED,
UNLOGIN
}
export interface ProfileState {
loginState: LOGIN_TYPES
user: any
error: string | null
}
let initialState: ProfileState = {
loginState: LOGIN_TYPES.UN_VALIDATE,
user: null,
error: null
}
export default function (state: ProfileState = initialState , action: AnyAction) {
switch (action.type) {
case actionsTypes.VALIDATE:
if (action.payload.success) {
return { ...state, user: action.payload.data, error: null }
} else {
return { ...state, user: null, error: action.payload.message }
}
default:
return state
}
}
分享到:

评论完整模式加载中...如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理