示例
useRef
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import React, { useState, useEffect, useRef, useContext } from 'react' const LikeButton: React.FC = () => { const likeRef = useRef(0) const domRef = useRef<HTMLInputElement>(null) useEffect(() => { if (domRef && domRef.current) { domRef.current.focus() } }) return ( <> <input type="text" ref={domRef} /> </> ) } export default LikeButton
|
点击useRef<HTMLInputElement>(null)
中的useRef
,跳转声明文件
1 2 3 4 5
| interface RefObject<T> { readonly current: T | null; } function useRef<T>(initialValue: T|null): RefObject<T>;
|
react-router
定义props
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import React from "react"; import { RouteComponentProps } from "react-router-dom";
interface MatchParams { touristRouteId: string; }
export const DetailPage: React.FC<RouteComponentProps<MatchParams>> = ( props ) => {
return <h1>路游路线详情页面, 路线ID: {props.match.params.touristRouteId}</h1>; };
|
对象Object
定义key类型,value类型
1 2 3 4 5 6 7 8 9 10 11 12 13
| interface IThemeProps { [key: string]: {color: string; background: string;} } const themes: IThemeProps = { 'light': { color: '#000', background: '#eee', }, 'dark': { color: '#fff', background: '#222', } }
|
withRouter
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
| import React from "react"; import { Image, Typography } from "antd"; import { withRouter, RouteComponentProps } from "react-router-dom";
interface PropsType extends RouteComponentProps { id: string | number; size: "large" | "small"; imageSrc: string; price: number | string; title: string; }
const ProductImageComponent: React.FC<PropsType> = ({ id, size, imageSrc, price, title, history, location, match }) => { return ( <div onClick={() => history.push(`detail/${id}`) }> </div> ); };
export const ProductImage = withRouter(ProductImageComponent);
|
redux
redux
原生的 redux 结合 react 使用的ts定义例子:
详细参考
react-redux
包含了 useSelector useDispatch connect 等等的使用技巧:
详细参考
其中一个 useSelector 定义ts 小技巧
以及完整的 react-redux 综合应用 就看 最后一节代码
state
解决 this.state.like 报错 Property 'like' does not exist on type 'Readonly<{}>'
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
| interface IState { like: any, } class LikeButton extends React.Component <any, IState>{ constructor(props:any){ super(props) this.state={like:0} } handleAlertClick =()=>{ const {like} = this.state; setTimeout(() => { alert('you clicked on ' + this.state.like) }, 3000)
setTimeout(() => { alert('you clicked on ' + like) }, 3000) }
render(){ const {like} = this.state; return ( <> <button onClick={() => {this.setState({like: like + 1});}}> {like} 👍 </button> {/* like 为 5 的时候, 点击触发 handleAlertClick, 然后一直点击上面的onClick改变like值,3秒后like值变成17 */} <button onClick={this.handleAlertClick}> Alert! </button> </> ) } }
|
style
1 2 3 4 5 6 7 8 9 10
| const wrapperStyle: React.CSSProperties = { padding: '20px 40px' }
const storyWrapper = (stroyFn: any) => ( <div style={wrapperStyle}> <h3>组件演示</h3> {stroyFn()} </div> )
|
createContext
1 2 3 4 5 6 7 8 9 10 11
| import React, { FC, useState, createContext, CSSProperties } from 'react'
interface IMenuContext { index: string; onSelect?: (selectedIndex: string) => void; mode?: MenuMode; defaultOpenSubMenus?: string[]; }
export const MenuContext = createContext<IMenuContext>({index: '0'})
|
click event : React.MouseEvent
1 2 3 4
| const handleClick = (e: React.MouseEvent) => { e.preventDefault() setOpen(!menuOpen) }
|
定义onChange type : React.ChangeEvent
1 2 3 4 5 6 7
| import React, { ChangeEvent } from 'react' export interface InputProps extends Omit<InputHTMLAttributes<HTMLElement>, 'size' > { onChange? : (e: ChangeEvent<HTMLInputElement>) => void; }
onChange={(e) => {e.target.value}}
|
定义键盘事件
1 2 3
| const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => { switch(e.keyCode) { }
|
props
按钮的props定义demo
demo
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
| export type ButtonSize = 'lg' | 'sm' export type ButtonType = 'primary' | 'default' | 'danger' | 'link'
interface BaseButtonProps { className?: string; disabled?: boolean; size?: ButtonSize; btnType?: ButtonType; children: React.ReactNode; href?: string; }
type NativeButtonProps = BaseButtonProps & ButtonHTMLAttributes<HTMLElement> type AnchorButtonProps = BaseButtonProps & AnchorHTMLAttributes<HTMLElement>
export type ButtonProps = Partial<NativeButtonProps & AnchorButtonProps>
export const Button: FC<ButtonProps> = (props) => {
|
按钮props
ButtonHTMLAttributes , 参考demo
锚点props
AnchorHTMLAttributes , 参考demo
ts 的 Partial
参考demo
运用场景
从一个对象类型中剔除某些属性 Omit
Omit
1 2 3 4 5 6 7 8 9 10 11 12
| import React, { FC, ReactElement, InputHTMLAttributes } from 'react' type InputSize = 'lg' | 'sm'
export interface InputProps extends Omit<InputHTMLAttributes<HTMLElement>, 'size' > { disabled?: boolean; size?: InputSize; append?: string | ReactElement; }
|
定义react element
参考上面的 demo : React.ReactElement
定义Promise
参考《type 的使用demo》
定义ref
以下也是 contains 的经典引用, 用于实现 点击元素之外任何地方 触发事件, 比如关闭弹框。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import { RefObject, useEffect } from "react";
function useClickOutside(ref: RefObject<HTMLElement>, handler: Function) { useEffect(() => { const listener = (event: MouseEvent) => { if (!ref.current || ref.current.contains(event.target as HTMLElement)) { return } handler(event) } document.addEventListener('click', listener) return () => { document.removeEventListener('click', listener) } }, [ref, handler]) }
export default useClickOutside
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import { FC } from 'react' import Menu, { MenuProps } from './menu' import SubMenu, { SubMenuProps } from './subMenu' import MenuItem, { MenuItemProps } from './menuItem'
export type IMenuComponent = FC<MenuProps> & { Item: FC<MenuItemProps>, SubMenu: FC<SubMenuProps> } const TransMenu = Menu as IMenuComponent
TransMenu.Item = MenuItem TransMenu.SubMenu = SubMenu
export default TransMenu
|
定义file 和 file列表
FileList 与 File 是 ts自带的类型【待进一步考证?】。
1 2 3 4 5 6
| const uploadFiles = (files: FileList) => { } const post = (file: File) => { }
|
type 的使用demo
示例一
1 2 3 4 5 6 7 8 9 10
| interface DataSourceObject { value: string; }
定义一个类型 DataSourceType 接收一个泛型,此泛型默认值为{} ,返回这个泛型 和 DataSourceObject 的并集 【是否并集待考证?】; export type DataSourceType<T = {}> = T & DataSourceObject export interface AutoCompleteProps extends Omit<InputProps, 'onSelect'> { fetchSuggestions: (str: string) => DataSourceType[] | Promise<DataSourceType[]>; }
|
示例二
参考《TransMenu.Item = MenuItem
类型定义》
调试经验
如何找到react元素的类型