react组件封装之三剑客(HOC、Render Props、Hook)

封装组件必然是为了逻辑复用,那么下面我们通过使用不同的封装方式去封装一个猫(HOC)、鼠(Render Props)、狗(Hook)跟着鼠标移动的逻辑组件,来看看组件封装的奥妙。

一:HOC(高阶组件)

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

 高阶组件其实就是一个参数是组件,返回值是新组件的函数。

import React from "react";

// HOC withSubscription 函数  WrappedComponent 需要被封装的组件
const withSubscription = WrappedComponent => {
    return class WithSubscription  extends React.Component {
        constructor(props) {
            super(props)
            this.state = {
                x: 0,
                y: 0,
            }
        }
        // 获取位置信息
        getSite = (e) => {
            this.setState({
                x: e.clientX,
                y: e.clientY,
            })
        } 

        componentDidMount() {
            document.addEventListener('mousemove', this.getSite)
        }

        componentWillUnmount() {
            document.removeEventListener('mousemove', this.getSite)
        }

        render() {
            return (
                
            )
        }
    }
}

// 对 CatTracker 进行装饰, 使其获得获取位置信息的能力
@withSubscription
class CatTracker extends React.Component {
    constructor(props) {
        super(props)
    }

    render() {
        const {x, y} = this.props
        return 
} } export default CatTracker

 二:Render Props

Render Props是指一种在 React 组件之间使用一个值为函数的 prop 共享代码的简单技术

import React from "react";

function Cat(Props) {
  const { x, y } = Props.mouse;
  return 
; } class Mouse extends React.Component { constructor(props) { super(props); this.state = { x: 0, y: 0, }; } // 获取位置信息 getSite = (e) => { this.setState({ x: e.clientX, y: e.clientY, }); }; componentDidMount() { document.addEventListener("mousemove", this.getSite); } componentWillUnmount() { document.removeEventListener("mousemove", this.getSite); } render() { return (
{this.props.render(this.state)}
); } } function MouseTracker() { return ( <>

鼠标!

} /> ); } export default MouseTracker;

通过props传递组件,有点类似slot的思想

 

三:Hook

Hook作用于函数组件,且我们可以使用自定义Hook.

import { useState, useEffect } from "react";

const useDog = () => {
    const [x, setX] = useState(0)
    const [y, setY] = useState(0)

    // 获取位置信息
    const getSite = (e) => {
        setX(e.clientX)
        setY(e.clientY)
    }

    useEffect(() => {
        document.addEventListener('mousemove', getSite)
        return () => {
            document.removeEventListener('mousemove', getSite)
        }
    })

    return {
        x,
        y
    }
}

const DogTracker = () => {
    const site = useDog()
    return (
        
) } export default DogTracker

 通过对同一逻辑进行不同方式的封装,Hook无疑看起来逻辑更清晰,复用更简单,而函数组件也更符合react的设计初衷。

 

你可能感兴趣的:(react,react)