共计 字 • 阅读约 min

什么是高阶组件

高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。

具体而言,高阶组件是参数为组件,返回值为新组件的函数。

上面两句话,是 react 文档中描述的高阶组件概念,不是很通俗易懂。如果你从来没有接触过高阶组件,你可能读完了会很懵逼。

这都不重要,让我们通过一个例子来认识高阶组件

使用高阶组件来实现组件逻辑抽离

假如我们现在有一个需求,多个组件都需要用到 window.innerWidthwindow.innerHeight 两个属性,并且需要随屏幕大小变化而改变

注: 我这里用到是函数组件和 hooks 写法,不熟悉的朋友可以先移步学习下 hooks

不用 HOC 的情况,我们的代码可能是这样的:

// 组件A
function ComA = () => {
    const [size, setSize] = useState({
	w: 0,
	h: 0
    })
    // 响应窗口大小处理函数
    const handleResize = () => {
        let w = window.innerWidth,
	    h = window.innerHeight
	setSize({
	    w,
	    h
	})
    }
    useEffect(() => {
        // 初始化数据
        handleResize()
        // 监听窗口大小变化
	window.addEventListener('resize', handleResize)
        // 组件销毁时,清除监听
	return () => {
            window.removeEventListener('resize', handleResize)
        }
    }, [])
    return <>
        <div>
            w:{size.w}
            h:{size.h}
        </div>
    </>
}

同样的逻辑,组件 B 也需要

// 组件B
function ComB = () => {
    const [size, setSize] = useState({
	w: 0,
	h: 0
    })
    // 响应窗口大小处理函数
    const handleResize = () => {
        let w = window.innerWidth,
	    h = window.innerHeight
	setSize({
	    w,
	    h
	})
    }
    useEffect(() => {
        // 初始化数据
        handleResize()
        // 监听窗口大小变化
	window.addEventListener('resize', handleResize)
        // 组件销毁时,清除监听
	return () => {
            window.removeEventListener('resize', handleResize)
        }
    }, [])
    return <>
        <div>
            w:{size.w}
            h:{size.h}
        </div>
    </>
}

显然,这样的代码过于耦合,不是一份合格的代码。所以我们现在利用 HOC,来抽离组件重复逻辑代码

// HOC高阶组件
// 自己本身是一个组件
function withSize(Component) {
    // 返回的也是一个组件
    return () => {
        // --------复用的逻辑---------
	const [size, setSize] = useState({
	    w: 0, 
	    h: 0
	})
	const handleResize = () => {
	    let w = window.innerWidth,
		h = window.innerHeight
	    setSize({
		w,
		h
	    })
	}
	useEffect(() => {
	    handleResize()
	    window.addEventListener('resize', handleResize)
	    return () => {
	        window.removeEventListener('resize', handleResize)
	    }
	}, [])
        // ------------------------
        // 视图内容,显示的的是高阶组件调用时,传递的组件,size数据通过组件props来传递
        return <Component {...size} />
    }
}

高阶组件的使用:

const SizeCom1 = ({ w, h }) => {
    return (
        <div>
	    <p>w:{w}</p>
	    <p>h:{h}</p>
	</div>
    )
}
const SizeCom2 = ({ w, h } ) => {
    return (
        <div>
	    <p>w:{w}</p>
	    <p>h:{h}</p>
	</div>
    )
}
const ComA = withSize(SizeCom1)
const ComB = withSize(SizeCom2)

function App(){
    return <>
        <ComA />
        <ComB />
    </>
}

image1619884742252.png



文章更新于: 2021-5-3 23:46:39