Skip to content

可参考文章:https://mp.weixin.qq.com/s/2ayQpXkGjsvUnBm7KPIYMg

1,封装 invariant函数来避免 | undefined 和 | null报错 (类型守卫)

ts
function invariant(condition:any,message?:string | (()=>string)):asserts condition{
    if(!condition){
        const errorMessage = typeof message === 'function' ? message() : message || 'Invariant violation';

        console.error("errorMessage",errorMessage)
    }
}

2, 封装HOC高阶组件转发Ref

ts
function  WithForwardedRef<T,P={}>(Component: React.ComponentType<T>){
    return forwardRef<T,P>((props,ref)=>{
        return <Component props={...props} ref={ref}/>
    })
}

3,twcss样式类名小寄巧

ts
import type { ClassValue } from "clsx";
import { clsx } from "clsx";
import { twMerge } from "tailwind-merge";

const cn = (...inputs: ClassValue[]) => {
  return twMerge(clsx(inputs));
};

export default cn;

4,

ts
type User = {
    id: number;
    name: string;
};

type UserRecord = Record<string, User>;

const users: UserRecord = {
    user1: { id: 1, name: 'Alice' },
    user2: { id: 2, name: 'Bob' },
};

5, 避免ref相关的问题

ts
// ❌ 错误示例:使用 ComponentProps
interface BadProps extends React.ComponentProps<"div"> {
    customProp: string;
}

// 这会导致类型错误,因为组件没有正确处理 ref
const BadComponent = (props: BadProps) => {
    return <div {...props} />;
};

// ✅ 正确示例:使用 ComponentPropsWithoutRef
interface GoodProps extends React.ComponentPropsWithoutRef<"div"> {
    customProp: string;
}

const GoodComponent = (props: GoodProps) => {
    return <div {...props} />;
};

6, forwardRef的正确使用

tsx
// 如果需要处理 ref,应该明确使用 forwardRef
interface ButtonProps extends React.ComponentPropsWithoutRef<"button"> {
    variant?: 'primary' | 'secondary';
}

// 正确处理 ref
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
    (props, ref) => {
        const { variant, ...rest } = props;
        return (
            <button 
                ref={ref}
                className={variant}
                {...rest}
            />
        );
    }
);
tsx
// ✅ 正确示例:使用 forwardRef
interface ButtonProps extends React.ComponentPropsWithoutRef<"button"> {
    label: string;
}

const Button = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => {
    const { label, ...rest } = props;
    return <button ref={ref} {...rest}>{label}</button>;
});

// 使用时 ref 可以正确工作
const App = () => {
    const buttonRef = useRef<HTMLButtonElement>(null);
    return <Button ref={buttonRef} label="Click me" />; // ref 正常工作
}

在React19中,有新写法: props直接合入ref当中

tsx
// React 19 的新写法
interface ButtonProps {
    label: string;
    ref?: React.Ref<HTMLButtonElement>;  // ref 直接作为 props
}

const Button = (props: ButtonProps) => {
    const { label, ref, ...rest } = props;
    return <button ref={ref} {...rest}>{label}</button>;
};

// 使用方式
const App = () => {
    const buttonRef = useRef<HTMLButtonElement>(null);
    return <Button ref={buttonRef} label="Click me" />;
}

7,

ts
// ❌ 可能的问题:ref 类型不匹配
interface ProblematicProps extends React.ComponentProps<"div"> {
    innerRef?: React.RefObject<HTMLDivElement>; // 与原生 ref 冲突
}

// ✅ 正确方式:
interface SafeProps extends React.ComponentPropsWithoutRef<"div"> {
    innerRef?: React.RefObject<HTMLDivElement>; // 不会与原生 ref 冲突
}
本站访客数 456 人次 本站总访问量 944
加载中