Introduction to the
When using React + typescript + ANTD, we often get confused about how to use the correct type definition. In this article, we will explain the common type definitions involved in this process one by one, along with some use cases. The purpose of this article is to keep a note for myself. I will not enumerate them here.
The react ts type definition is broken down
React internal component definitions
React.ReactText
- string
- number
React.ReactChild
- ReactText
- The React components
React.ReactNode
- ReactChild
- ReactFragment
- ReactPortal
- boolean
- null
- undefined
const elementOrPrimitive: React.ReactNode = 'string' || 0 || false || null || undefined || <div /> || <MyComponent />;
const Component = ({ children: React.ReactNode }) = >.Copy the code
React.CSSProperties
React CSS property, which represents a Style Object in a JSX file (usually used in CSS-in-JS)
const styles: React.CSSProperties = { flexDirection: 'row'.const element = <div style={styles} .
Copy the code
React.FunctionComponent<P={}>
FC<P={}>, stateless component (SFC), type definition of a function component, a generic interface that accepts a parameter, optionally passed, to define the type of props.
interface EditorsProps {
detail: string
}
// const Editors:React.FunctionComponent<EditorsProps> = (props) => {
const Editors: React.FC<EditorsProps> = (props) = > {
const { detail } = props;
return (<>{detail}</>);
};
Copy the code
Component<P,S={}>/PureComponent<P,S={}>
A generic class that takes two arguments, the first is a type definition for props and the second is a type definition for state (which can be omitted if a parent component passes a property method or defines state, but is not required if it does not, as is the case without TypeScript).
import React, { Component } from 'react'
import { RouteComponentProps } from 'react-router-dom';
interface CountProps extends RouteComponentProps {// Can inherit from other interface types
count: number;
asyncAddCount: (count: number) = > void;
asyncReduceCount: (count: number) = > void;
}
interface CountStateType{// Only defined when needed
}
class Counter extends Component<CountProps.CountStateType> {
render(): JSX.Element{
const { count, asyncAddCount, asyncReduceCount } = this.props;
return (
<div>
<h2>{count}</h2>
<button onClick={asyncAddCount.bind(null, 10)} >Counter++</button>
<button onClick={asyncReduceCount.bind(null, 10)} >Counter--</button>
</div>)}}Copy the code
JSX.Element
orReact.ReactElement<P>
The JSX syntax type returned by return, as in render above.
const elementOnly: React.ReactElement = <div /> || <MyComponent />;
Copy the code
- ComponentClass<P,S={}>
The class type, the generic interface, can be used in higher-order components when receiving a class or function.
import React, { Context, FC, ComponentClass, createContext, useReducer } from 'react';
const ProviderContext: Context<any> = createContext('provider');
export default const RootProvider = (reducer: Function, initialState: any) = > (Com: FC<any> | ComponentClass<any.any>) = > {
return () = > {
const [state, dispatch] = useReducer<any>(reducer, initialState);
return (
<ProviderContext.Provider value={{ state.dispatch}} >
<Com /></ProviderContext.Provider > ); }}Copy the code
Context
The type of context is what it is, a generic interface.
// The type definition of the source code is as follows: we can see that we need to pass a type so that the parameter types are consistent
interface Context<T> {
Provider: Provider<T>; Consumer: Consumer<T>; displayName? :string;
}
Copy the code
Dispatch<any>
A generic interface to define the type of dispatches, often used in dispatches generated by useReducer.
// Create an asynchronous action function that returns an asynchronous action object
const asyncAction = (dispatch: Dispatch<any>) = > {
return {
asyncAddaction() {
console.log('Before executing addActions:' + Date.now());
setTimeout(() = > {
console.log('Execute addActions:' + Date.now());
dispatch(addActions());
}, 1000); }}}Copy the code
LazyExoticComponent
Lazy loaded types, generic interfaces, can accept various types of arguments, as the case may be, for example:
export interface RouteType {
pathname: string;
component: LazyExoticComponent<any>;
exact: boolean; title? :string; icon? :string; children? : RouteType[]; }export const AppRoutes: RouteType[] = [
{
pathname: '/login'.component: lazy(() = > import('.. /views/Login/Login')),
exact: true
},
{
pathname: '/ 404'.component: lazy(() = > import('.. /views/404/404')),
exact: true}, {pathname: '/'.exact: false.component: lazy(() = > import('.. /views/Admin/Admin'))}]Copy the code
RefForwardingComponent<T, P = {}>
ForwardRef, ref Forward type definition, generic interface, receive two parameters.
forwardRef(Editors) as RefForwardingComponent<any.any>;
// is the type of ref and props, respectively, and can be defined as any for simplicity
// The source types are defined as follows
interface RefForwardingComponent<T, P = {}> {
(props: PropsWithChildren<P>, ref: Ref<T>): ReactElement | null; propTypes? : WeakValidationMap<P>; / contextTypes? : ValidationMap<any>; defaultProps? : Partial<P>; displayName? :string;
}
Copy the code
MutableRefObject<any>
A generic interface that accepts one parameter, which can be of any type, as the type definition for useRef.
const prctureRef: React.MutableRefObject<any> = useRef();
Copy the code
useState<any>
The useState of hooks is a generic function that passes a type to define the hooks.
const [isShowAdd, setIsShowAdd] = useState<boolean> (false);
Copy the code
UseRef is also a generic function that can be passed to a type if you want to be more precise. UseReducer is also a generic function.
Other:
interface IProps{
name: React.ReactText; children? : React.ReactChild; header? : React.ReactNode; }Copy the code
React-router common type
RouteComponentProps
The most common type of routing the API definition, includes the history, location, match, staticContext type definition of the four routing API
import React from 'react';
import { RouteComponentProps } from 'react-router-dom';
export default function Admin({ history, location, match }: RouteComponentProps) {
return(<>This is the home page</>);
}
Copy the code
React internal event definitions
FormEvent
A React form form has the event type.
<form onSubmit={(e:FormEvent)= >{ e.preventDefault(); }} ></form>
Copy the code
ChangeEvent
The react onChange event triggers the event type. This is a generic interface and uses the following:
<input
type="text"
value={count}
onChange={(e: ChangeEvent<HTMLInputElement>) => { setCount(e.currentTarget.value); //HTMLInputElement represents an HTML input node}} />Copy the code
Optional generic types :HTMLSelectElement, HTMLInputElement, HTMLDivElement, HTMLTextAreaElement and other HTML tag nodes of all types. There are various other event handling types, which can be viewed at @types/ React.
SyntheticEvent<T = Element, E = Event>
Generic interfaces, event wrappers, which are collections of native events, are combinations of native events.
Your event handler will pass an instance of SyntheticEvent, which is a cross-browser native event wrapper. (Official introduction)
<button onClick={(e:SyntheticEvent<Element.Event>) = > {}} ></button>
<input onChange={(e:SyntheticEvent<Element.Event>) = > {}} / ><form
onSubmit={(e: SyntheticEvent<Element.Event>) => {}}
onBlur={(e: SyntheticEvent<Element, Event>) => {}}
onKeyUp={(e: SyntheticEvent<Element, Event>) => {}}
>
</form>
Copy the code
As you can see from the above, the generic interface for composing events can be applied to any event.
- Other event types are not completely exemplified
Sample code:
import React, { FC, ReactElement, MouseEvent } from 'react'
type Props = {
label: string.children: ReactElement, onClick? :(e: MouseEvent<HTMLButtonElement>) = > void
}
const FunctionComponent: FC<Props> = ({ label, children, onClick }: Props) = > {
return (
<div>
<span>{label} :</span>
<button type="button" onClick={onClick}>
{children}
</button>
</div>)}export default FunctionComponent
Copy the code
React.ReactEventHandler<HTMLElement>
Common React Event Handler
const handleChange: React.ReactEventHandler<HTMLInputElement> = (ev) = >{... } <input onChange={handleChange} ... />Copy the code
Type definition of Antd
FormComponentProps
For use with the Form component
import React from 'react';
import { Form } from 'antd';
import { FormComponentProps } from 'antd/lib/form';
interface AddFormProps extends FormComponentProps {
}
function AddForm({ form }: AddFormProps) {
return (
<Form></Form>
);
}
export default Form.create()(AddForm) as any;
Copy the code
The type of the form is WrappedFormUtils, which is normally defined when the form is assigned.
ColumnProps<any>
The type of each entry of the columns property of the table definition, with the any parameter indicating the type of table data, as shown in the following example:
interface ProductType {
key:string;
name:string;
desc:string
}
const columns: ColumnProps<ProductType>[] = [
{
title: 'Trade Name'.dataIndex: 'name'
},
{
title: 'Merchandise Details'.dataIndex: 'desc'}]Copy the code
Third, other
Promise<any>
interface IResponse<T> {
message: string.result: T,
success: boolean,}async function getResponse () :Promise<IResponse<number[] > >{
return {
message: 'Obtain success'.result: [1.2.3].success: true,
}
}
getResponse()
.then(response= > {
console.log(response.result)
})
Copy the code
axios
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'
const server: AxiosInstance = axios.create();
server.interceptors.request.use((config: AxiosRequestConfig) = > {// Request interception
return config;
});
server.interceptors.response.use((res: AxiosResponse) = > {
if (res.status === 200) {
res = res.data;
}
return res;
},(err:AxiosError) = >{});
Copy the code