You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在HOC中为包裹的React组件注入Prop Types

React HOC自动注入WindowSize类型的解决方案

问题背景

现有如下监听窗口尺寸的HOC:

import React, {useEffect, useState} from 'react'

interface WindowSize {
    width: number,
    height: number
}

export function WithWindowSize <T>(Component: React.ComponentType<T>) {
    return function WithComponent(props: T) {
        const [windowSize, setWindowSize] = useState({} as WindowSize)

        useEffect(() => {
            ...
        }, [])

        return <Component
            {...props}
            windowSize={windowSize}/>
    }
}

export default WithWindowSize;

使用该HOC时尝试手动合并类型,出现报错:

interface FooProps {
    headline: string,
    value: string | number,
}

// 此处存在拼写错误:FoooProps → FooProps
const Foo = ({headline, value, windowSize}: FooProps & WindowSize) => {
    return ...
}

export default WithWindowSize(Foo);

报错信息:

类型“FooProps & WindowSize”上不存在属性“windowSize”。

需求:希望在HOC内部实现WindowSize类型的自动注入,避免每次使用时手动处理类型合并。

解决方案

问题核心在于HOC的泛型定义逻辑错误,需要调整泛型约束,让TypeScript明确:传入的组件需要包含WindowSize类型的Props,而返回的组件仅需接收用户自定义的Props(WindowSize由HOC自动注入)。

修改后的HOC代码

import React, {useEffect, useState} from 'react'

interface WindowSize {
    width: number,
    height: number
}

// 泛型调整:传入组件接收「用户自定义Props(T) + WindowSize」,返回组件仅接收T
export function WithWindowSize<T>(Component: React.ComponentType<T & WindowSize>) {
    return function WithComponent(props: T) {
        // 初始化窗口尺寸,避免空对象类型警告
        const [windowSize, setWindowSize] = useState<WindowSize>({
            width: window.innerWidth,
            height: window.innerHeight
        });

        useEffect(() => {
            // 实现窗口resize监听逻辑
            const handleResize = () => {
                setWindowSize({
                    width: window.innerWidth,
                    height: window.innerHeight
                });
            };

            window.addEventListener('resize', handleResize);
            // 组件卸载时清理监听
            return () => window.removeEventListener('resize', handleResize);
        }, []);

        return <Component
            {...props}
            windowSize={windowSize}/>
    }
}

export default WithWindowSize;

使用方式(无需手动合并类型)

interface FooProps {
    headline: string,
    value: string | number,
}

// 直接解构windowSize,类型由HOC自动注入,无需手动声明WindowSize
const Foo = ({headline, value, windowSize}: FooProps) => {
    return (
        <div>
            <h1>{headline}</h1>
            <p>当前值: {value}</p>
            <p>窗口宽度: {windowSize.width}</p>
            <p>窗口高度: {windowSize.height}</p>
        </div>
    );
}

export default WithWindowSize(Foo);

关键说明

  • 调整泛型约束后,TypeScript会自动识别被HOC包裹的组件可直接使用windowSize属性,无需在组件Props类型中手动合并WindowSize
  • 修复了原代码中useState初始化空对象的类型不安全问题,直接用当前窗口尺寸初始化状态
  • 补充了完整的窗口resize监听与清理逻辑,保证功能完整性与内存安全

内容的提问来源于stack exchange,提问作者four-eyes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 09:37:11