react 高阶组件HOC实现组件复用

目录

一 使用步骤

二 显示鼠标坐标

 三 鼠标随图片移动

四 设置displayName

五 传递props


高阶组件HOC: Higher-Order Component,是一个函数,接收要包装的组件,返回增强后的组件
目的:实现状态逻辑复用
高阶组件就相当于手机壳, 采用包装(装饰)模式

一 使用步骤


1 创建一个函数,名称约定以with开头
2 指定函数的参数,参数以大写字母开头(作为要渲染的组件)
3 在函数内部创建一个类组件,提供复用的状态逻辑代码,并返回
4 渲染参数组件,同时将状态通过props传递给参数组件
5 调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面中

二 显示鼠标坐标

import React from "react";
import ReactDOM from "react-dom";

// 1 创建一个函数,名称约定以with开头
// 2 指定函数的参数,参数以大写字母开头(作为要渲染的组件)
function withMouse(WrappedComponent) {

    // 3 在函数内部创建一个类组件,提供复用的状态逻辑代码,并返回
    class Mouse extends React.Component {

        //鼠标状态
        state = {
            x: 0,
            y: 0
        }

        //处理状态的逻辑代码
        handleMouseMove = e => {
            this.setState({
                x: e.clientX,
                y: e.clientY
            })
        }

        //监听鼠标移动事件
        componentDidMount() {
            window.addEventListener("mousemove", this.handleMouseMove)
        }

        //解绑事件
        componentWillUnmount() {
            window.removeEventListener('mousemove', this.handleMouseMove)
        }

        render() {
            //4 渲染参数组件,同时将状态通过props传递给参数组件
            return 

        }

    }
    return Mouse;
}

const Position = props => (
    

鼠标当前位置:(x:{props.x},y:{props.y})

) //调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面中 const MousePosition = withMouse(Position) class App extends React.Component { render() { return (
{/*渲染增强后的组件*/}
) } } ReactDOM.render(, document.getElementById("root"));

效果

react 高阶组件HOC实现组件复用_第1张图片

 三 鼠标随图片移动

加入鼠标随图片移动的功能

import imgage from "./images/cat.jpg"

const Cat = props => (
    猫
)


//调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面中
const MousePosition1 = withMouse(Cat)

效果

react 高阶组件HOC实现组件复用_第2张图片

完整代码

import React from "react";
import ReactDOM from "react-dom";
import imgage from "./images/cat.jpg"

// 1 创建一个函数,名称约定以with开头
// 2 指定函数的参数,参数以大写字母开头(作为要渲染的组件)
function withMouse(WrappedComponent) {

    // 3 在函数内部创建一个类组件,提供复用的状态逻辑代码,并返回
    class Mouse extends React.Component {

        //鼠标状态
        state = {
            x: 0,
            y: 0
        }

        //处理状态的逻辑代码
        handleMouseMove = e => {
            this.setState({
                x: e.clientX,
                y: e.clientY
            })
        }

        //监听鼠标移动事件
        componentDidMount() {
            window.addEventListener("mousemove", this.handleMouseMove)
        }

        //解绑事件
        componentWillUnmount() {
            window.removeEventListener('mousemove', this.handleMouseMove)
        }

        render() {
            //4 渲染参数组件,同时将状态通过props传递给参数组件
            return 

        }

    }
    return Mouse;
}


const Cat = props => (
    猫
)


//调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面中
const MousePosition1 = withMouse(Cat)

const Position = props => (
    

鼠标当前位置:(x:{props.x},y:{props.y})

) //调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面中 const MousePosition2 = withMouse(Position) class App extends React.Component { render() { return (
{/*渲染增强后的组件*/}
) } } ReactDOM.render(, document.getElementById("root"));

四 设置displayName

默认情况下,react使用组件名称作为displayName
使用高阶组件存在的问题: 得到的两个组件名称相同

react 高阶组件HOC实现组件复用_第3张图片
解决办法: 设置displayName → 用于调试时区分不同的组件

react 高阶组件HOC实现组件复用_第4张图片

 效果

react 高阶组件HOC实现组件复用_第5张图片完整代码

import React from "react";
import ReactDOM from "react-dom";
import imgage from "./images/cat.jpg"

// 1 创建一个函数,名称约定以with开头
// 2 指定函数的参数,参数以大写字母开头(作为要渲染的组件)
function withMouse(WrappedComponent) {

    // 3 在函数内部创建一个类组件,提供复用的状态逻辑代码,并返回
    class Mouse extends React.Component {

        //鼠标状态
        state = {
            x: 0,
            y: 0
        }

        //处理状态的逻辑代码
        handleMouseMove = e => {
            this.setState({
                x: e.clientX,
                y: e.clientY
            })
        }

        //监听鼠标移动事件
        componentDidMount() {
            window.addEventListener("mousemove", this.handleMouseMove)
        }

        //解绑事件
        componentWillUnmount() {
            window.removeEventListener('mousemove', this.handleMouseMove)
        }

        render() {
            //4 渲染参数组件,同时将状态通过props传递给参数组件
            return 

        }

    }

    //设置displayName
    Mouse.displayName = `withMouse${getDisplayName(WrappedComponent)}`
    return Mouse;
}
//displayName
function getDisplayName(WrappedComponent) {
    return WrappedComponent.displayName || WrappedComponent.name || 'Component'
}

const Cat = props => (
    猫
)


//调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面中
const MousePosition1 = withMouse(Cat)

const Position = props => (
    

鼠标当前位置:(x:{props.x},y:{props.y})

) //调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面中 const MousePosition2 = withMouse(Position) class App extends React.Component { render() { return (
{/*渲染增强后的组件*/}
) } } ReactDOM.render(, document.getElementById("root"));

五 传递props

问题:

添加了一个属性, 打印了props

react 高阶组件HOC实现组件复用_第6张图片

 属性没显示在props里

原因:props传递丢失

解决办法:

react 高阶组件HOC实现组件复用_第7张图片

 效果

 完整代码

import React from "react";
import ReactDOM from "react-dom";


// 1 创建一个函数,名称约定以with开头
// 2 指定函数的参数,参数以大写字母开头(作为要渲染的组件)
function withMouse(WrappedComponent) {

    // 3 在函数内部创建一个类组件,提供复用的状态逻辑代码,并返回
    class Mouse extends React.Component {

        //鼠标状态
        state = {
            x: 0,
            y: 0
        }

        //处理状态的逻辑代码
        handleMouseMove = e => {
            this.setState({
                x: e.clientX,
                y: e.clientY
            })
        }

        //监听鼠标移动事件
        componentDidMount() {
            window.addEventListener("mousemove", this.handleMouseMove)
        }

        //解绑事件
        componentWillUnmount() {
            window.removeEventListener('mousemove', this.handleMouseMove)
        }

        render() {
            //4 渲染参数组件,同时将状态通过props传递给参数组件
            return 

        }

    }

    return Mouse;
}


const Position = props => {
    console.log(props)
    return (
        

鼠标当前位置:(x:{props.x},y:{props.y})

) } //调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面中 const MousePosition = withMouse(Position) class App extends React.Component { render() { return (
{/*渲染增强后的组件*/}
) } } ReactDOM.render(, document.getElementById("root"));

你可能感兴趣的:(react,前端,react.js)