本文共 12414 字,大约阅读时间需要 41 分钟。
翻译自 ,作者:Piotrek Witek
翻译自 ,作责:Yusuke Mori
参考文章
概述:最近在学习 react&TypeScript,发现有许多的组件模式和方法需要去梳理和总结。所以选择一些文章用于沉淀和思考,记录下一些知识点,和大家探讨。
publish:2019-03-21
目录:
React - 关键类型
展示性组件(FunctionComponent
)
React.FunctionComponent<P>
or React.FC<P>
。
const MyComponent: React.FC<Props> = ...
有状态组件(ClassComponent
)
React.Component<P, S>
class MyComponent extends React.Component<Props, State> { ...
组件Props
React.ComponentProps<typeof Component>
获取组件(适用于ClassComponent、FunctionComponent)的Props的类型
type MyComponentProps = React.ComponentProps<typeof MyComponent>;
React.FC | React.Component的联合类型
React.ComponentType<P>
123 | const withState = |
React 要素
React.ReactElement<P>
or JSX.Element
表示React元素概念的类型 - DOM组件(例如
)或用户定义的复合组件()
const elementOnly: React.ReactElement = <div /> || <MyComponent />;
React Node
React.ReactNode
表示任何类型的React节点(基本上是ReactElement(包括Fragments和Portals)+ 原始JS类型 的合集)
12 | const elementOrPrimitive: React.ReactNode = 'string' || 0 || false || null || undefined || || |
React CSS属性
React.CSSProperties
代表着Style Object在 JSX 文件中(通常用于 css-in-js)
12 | const styles: React.CSSProperties = { flexDirection: 'row', ...const element = |
通用的 React Event Handler
React.ReactEventHandler<HTMLElement>
123 | const handleChange: React.ReactEventHandler |
特殊的 React Event Handler
React.MouseEvent<E>
| React.KeyboardEvent<E>
| React.TouchEvent<E>
123 | const handleChange = (ev: React.MouseEvent |
React 组件模式
Function Components - FC 纯函数组件(无状态)
顾名思义,纯函数组件本身不具备 State
,所以没有状态,一切通过 Props
12345678910111213141516171819202122 | import React, { FC, ReactElement, MouseEvent } from 'react'type Props = { label: string, children: ReactElement, onClick?: (e: MouseEvent |
扩展属性(spread attributes)
利用 ...
对剩余属性进行处理
12345678910111213141516171819202122 | import React, { FC, ReactElement, MouseEvent, CSSProperties } from 'react'type Props = { label: string, children: ReactElement, className?: string, style?: CSSProperties, onClick?: (e: MouseEvent |
默认属性
如果,需要默认属性,可以通过默认参数值来处理
123456789101112131415161718192021 | import React, { FC, ReactElement, MouseEvent } from 'react'type Props = { label?: string, children: ReactElement,}const FunctionComponent: FC |
Class Components
相对于FC,多了 state
,采用如下形式来定义Class Component
这一部分的写法,与相同,觉得结构很清晰,复用。
1234567891011121314151617181920212223242526272829303132333435363738 | import React, { Component } from 'react';type Props = { label: string}const initialState = { count: 0}type State = Readonly |
默认属性
处理 Class Component 的默认属性,主要有两种方法:
withDefaultProps
来定义默认属性,涉及组件的属性的类型转换;static props
以及 componentWillReceiveProps
,处理默认属性。具体业务中,视情况而定,第一中可以查看相关文章,这里介绍第二种
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748 | import React, { Component } from 'react';type Props = { label: string, initialCount: number}type State = { count: number;}class ClassCounter extends Component |
通用组件 Generic Components
12345678910111213141516 | import React, { Component, ReactElement } from 'react'interface GenericListProps |
Render Callback & Render Props
Render Callback,也被称为函数子组件,就是将 children 替换为 () => children;
Render Props,就是将 () => component 作为 Props 传递下去。
1234567891011121314151617181920212223242526272829 | import React, { Component, ReactElement } from 'react';type Props = { PropRender?: () => ReactElement, children?: () => ReactElement}class PropRender extends Component |
HOC(Higher-Order Components)
简单理解为,接受React组件作为输入,输出一个新的React组件的组件的工厂函数。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546 | import * as React from 'react'interface InjectedProps { label: string}export const withState = |
Redux - 使用以及 Redux Thunk 使用
以如下形式来介绍Redux,主要是in-ts的使用:
(prestate, action) => state;
使用Redux Thunk 来出来异步操作。
123456789101112131415 | // store.jstype DataType = { counter: number}const DataState: DataType = { counter: 0}type RootState = { Data: DataType}export default RootState |
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 | // action.jsimport { Action, AnyAction } from 'redux'import { ThunkAction, ThunkDispatch } from 'redux-thunk'import RootState from '../store/index'type IncrementPayload = { value: number}interface IncrementAction extends Action { type: 'INCREMENT', payload: IncrementPayload}export const Increment = ({ value }: IncrementPayload): IncrementAction => { const payload = { value } return { type: 'INCREMENT', payload }}export type DecrementPayload = { value: number;};export interface DecrementAction extends Action { type: 'DECREMENT'; payload: DecrementPayload;}export type RootAction = IncrementAction & DecrementAction;export const asyncIncrement = ( payload: IncrementPayload): ThunkAction |
123456789101112131415 | // reducer.jsimport { DataState, DataType } from '../store/Data'import { RootAction } from '../actions/'export default function (state: DataType = DataState, { type, payload }: RootAction): DataType { switch(type) { case 'INCREMENT': return { ...state, counter: state.counter + payload.value, }; default: return state; }} |
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 | // Hearder.jsimport React, { Component, ReactNode } from 'react'import RootState from '../store/index'import { Dispatch, AnyAction } from 'redux'import { ThunkDispatch } from 'redux-thunk'import { connect } from 'react-redux'import { Increment, asyncIncrement } from '../actions/'const initialState = { name: 'string'}type StateToPropsType = Readonly<{ counter: number}>type DispatchToPropsType = Readonly<{ handleAdd: () => void, handleDec: () => void}>type StateType = Readonly |
原文
y
转载地址:http://dyzii.baihongyu.com/