TS组件定义语法(React)

101 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

TS组件定义语法(React)

1、React.FC< P >,React内置函数

React.FC<>是函数式组件在TypeScript使用的一个泛型,FC就是FunctionComponent的缩写,事实上React.FC可以写成React.FunctionComponent。

import React from 'react';
 
interface demo1PropsInterface {
    attr1: string,
    attr2 ?: string,
    attr3 ?: 'w' | 'ww' | 'ww'
};
 
// 函数组件,其也是类型别名
// type FC<P = {}> = FunctionComponent<P>;
// FunctionComponent<T>是一个接口,里面包含其函数定义和对应返回的属性
// interface FunctionComponent<P = {}> {
//      // 接口可以表示函数类型,通过给接口定义一个调用签名实现
//      (props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;
//      propTypes?: WeakValidationMap<P> | undefined;
//      contextTypes?: ValidationMap<any> | undefined;
//      defaultProps?: Partial<P> | undefined;
//      displayName?: string | undefined;
// }
const Demo1: React.FC<demo1PropsInterface> = ({
    attr1,
    attr2,
    attr3
}) => {
    return (
        <div>hello demo1 {attr1}</div>
    );
};
 
export default Demo1;
2、React.Component<P,S>

React.Component< P, S > 是定义class组件的一个泛型,第一个参数是props、第二个参数是state。

import React from "react"

//props接口
interface demo2PropsInterface {
    props1: string
}

//state接口
interface demo2StateInterface {
    state1: string
}

class Demo2 extends React.Component<demo2PropsInterface,demo2StateInterface> {
    constructor(props: demo2PropsInterface){
        super(props);
        this.state = {
            state1: 'state1'
        }
    }
  
    render() {
        return (
          <div>{this.state.state1 + this.props.props1}</div>
        )
    }
}
3、React.createContext、useContext和useReducer
3.1、React.createContext

React.createContext会创建一个Context对象,当React渲染一个订阅了这个Context对象的组件,这个组件会从组件树中离自身最近的那个匹配的Provider中读取到当前的context值。【注:只要当组件所处的树没有匹配到Provider时,其defaultValue参数参会生效】

const MyCOntext = React.createContext(defaultValue)

const Demo = () => {
    return (
        //注:每个context对象都会返回一个Provider组件,它允许消费组件订阅context的变化
     <MyContext.Provider value={XXXX}>
       //.....   
     </MyContext.Provider>
    )
}
3.2、useContext

接收一个context对象(React.createContext的返回值)并返回该context的当前值,当前的context值由上层组件中距离当前组件最近的<MyContext.Provider>的value prop决定。语法:[const value = useContext(MyContext)]

import React, {useContext} from "react";
const MyContext = React.createContext('')

const Demo3Child: React.FC<{}> = () => {
    const context = useContext(MyContext)
  
    return (
    <div>{context}</div>
    )
}

const Demo3:React.FC<{}> = () => {
    constb [state,dispatch] = useReducer(reducerinitialState);
    return (
     <MyContext.Provider value={'2222222'}>
       <MyContext.Provider value={'333'}>
           <Demo3Child   />
       </MyContext.Provider>   
     </MyContext.Provider>
    )
}
3.3、useReducer

useState的替代方案,接收一个形如(state,action) => newState的reducer,并返回当前state以及其配套的dispatch方法,语法:const [state,dispatch] = useReducer(reducer,initialArg,init)

import React,{ useReducer,useContext } from "react";
interface stateInterface {
    count:number
}

interface actionInterface {
    type: string,
    data: {
        [propName: string]: any
    }
};
const initialState = {
    count: 0
}

//React.Reducer其实是类型别名,其实质上type Reducer<S,A> = (prevState:S, action: A) => S;
//因为reducer是一个函数,其接受两个泛型参数S和A,返回S类型

const reducer:React.Reducer<stateInterface,actionInterface> = (state,action) => {
    const {type, data} =action
    switch (type) {
        case 'increment': {
            return {
                ...state,
                count: state.count + data.count
            }
        }
        case 'decrement': {
            return {
                ...state,
                count: state.count - data.count
            };
        }
        default: {
            return state
        }
    }
}

//React.createContext返回的是一个对象,对象接口用接口表示
//传入泛型参数作为接口的参数
interface Context<T> {
    Provider: Provider<T>,
    Consumer: Consumer<T>,
    displayName?:string | undefined
}

const MyContext: React.Context<{
    state: stateInterface,
    dispatch?:React.dispatcher<actionInterface>
}> = React.createContext({
    state:initialState
})

const Demo3Child: React.FC<{}> = () => {
    const {state, dispatch} = useContext(MyContext);
    const handleClick = () => {
        if (dispatch) {
            dispatch({
                type: 'increment',
                data: {
                    count: 10
                }
            })
        }
    };
    return (
        <div>
            {state.count}
            <button onClick={handleClick}>增加</button>
        </div>
    );
}
 
const Demo3: React.FC<{}> = () => {
    const [state, dispatch] = useReducer(reducer, initialState);
 
    return (
        <MyContext.Provider value={{state, dispatch}}>
            <Demo3Child />
        </MyContext.Provider>
    );
};
 
export default Demo3;
————————————————
原文链接:https://blog.csdn.net/wang_yu_shun/article/details/123675804
  

React TS中的事件处理

1、不带参数event
const Test: React.FC<{}> = () => {
    const handleClick = () => {}
  
    return (
    <div>
        <Button onClick={handleClick}>
            按钮
        </Button>
     </div>
    )
}
2、带参数event

当事件处理函数带event参数时,如果不做任何处理会报错

//带event参数
const Test: React.FC<{}> = () => {
    //报错,
    const handleClick = (event) => {}
      event.preventDefault()
    return (
    <div>
        <Button onClick={handleClick}>
            按钮
        </Button>
     </div>
    )
}
1、点击event参数跳转到index.d.ts文件查看参数定义
//onClick是MouseEventHandler类型
onClick?:MouseEventHandler<T> | undefined
//MouseEventHandler<T>是什么呢?原来是个类型别名,泛型是Element类型
type MouseEventHandler< T = Element > = EventHandler<MouseEvent<T>>
  
//泛型Element是什么,是一个接口
   interface Element {}
   interface HTMLElement extends Elements { }
2、带参数Event的事件实现
const Test: React.FC<{}> = () => {
    const handleClick: React.MouseEventHandler<HTMLButtonElement> = event => {
        event.preventDefault()
    }
    return (
     <div>
      <button onClick={handleClick}>按钮</button>   
     </div>
    )
}