React高阶组件的应用

这一生的挚爱 提交于 2020-11-03 16:32:15

题图 From Bing By Clm


今天跟大家聊一聊React的高阶组件,那么什么是高阶组件呢?


如果一个函数 接受一个或多个组件作为参数并且返回一个组件 就可称之为 高阶组件。


高阶组件的本质就是一个函数,这个函数的参数是组件,这个函数的返回结果是一个组件。


我们用一个案例来说明,封装一个Mouse组件,这个组件实时获取鼠标的坐标并实时显示出来。


代码如下:


import React,{Component} from 'react';class Mouse extends Component {    constructor(props) {        super(props);        this.state = {            x:0,            y:0        }    }    handleMouse=(e)=>{        this.setState({            x:e.clientX,            y:e.clientY        })    }    render() {        return <div            onMouseMove={this.handleMouse}            style={{                background:"red",                height:"100px",                width:"500px",            }}        >            <h1>x:{this.state.x}</h1>            <h1>y:{this.state.y}</h1>        </div>    }}export default Mouse;


显示结果:



代码很简单,在一个div上面监听鼠标的拖动事件,实时获取坐标,并将其显示出来,在此基础之上,我们将其改造成高阶组件。


这里面需要明白几个问题,为什么要改造呢?如何改造呢?


首先来搞清楚第一个问题:假如我们的项目中有多个组件需要获取鼠标的坐标,有的组件只是显示,有的组件需要根据坐标来移动dom元素,我们改如何做呢?简单直白的方法,直接copy上面的代码,修改代码,有多少组件需要实时获取鼠标坐标就copy修改几次。


这显然不是最好方案,我们可以将获取鼠标坐标的逻辑抽离出来,构造一个高阶组件,那么如何构造呢?


再次重申一下高阶组件的定义:

如果一个函数 接受一个或多个组件作为参数并且返回一个组件 就可称之为 高阶组件。


我们根据这个定义书写代码:

// 1、定义一个函数// 2、参数为组件function HOC(Comp){    //3、调用后,返回一个组件    return class extends Component{        constructor(props) {            super(props);        }        render() {            return <div>                {/*2、参数为组件*/}                <Comp/>            </div>        }    }}


以上代码便是高阶组件最简单的代码结构,下面我们来填充上面的代码,首先我们要明白,高阶组件内部返回的组件的通用逻辑是什么呢?获取鼠标的移动坐标。

代码进一步完善如下:


import React,{Component} from 'react';
// 1、定义一个函数// 2、参数为组件function HOC(Comp){ //3、调用后,返回一个组件 return class extends Component{ constructor(props) { super(props); //4、保存鼠标坐标位置 this.state = { x:0, y:0 } } //5、鼠标移动获取新的位置坐标 handleMouse =(e)=>{ this.setState({ x:e.clientX, y:e.cclientY }) } render() {            return <div onMouseMove={this.setState}> {/*6将获取到的坐标传递给目标组件*/} <Comp x={this.state.x} y={this.state.y}/> </div> } }}


阅读源码:我们在高阶组件的结构上增加了如下几个功能,定义state保存鼠标位置,监听鼠标移动事件获取新的坐标,将坐标传递给目标组件。


下面我们完成目标组件,目标组件的作用主要是显示坐标。代码如下:


class Show extends Component{    constructor(props) {        super(props);    }    render() {        return <div>            <h2>x:{this.props.x}</h2>            <h2>x:{this.props.y}</h2>        </div>    }}


最终代码如下:


import React,{Component} from 'react';
// 1、定义一个函数// 2、参数为组件function HOC(Comp){ //3、调用后,返回一个组件 return class extends Component{ constructor(props) { super(props); //4、保存鼠标坐标位置 this.state = { x:0, y:0 } } //5、鼠标移动获取新的位置坐标 handleMouse =(e)=>{ this.setState({ x:e.clientX, y:e.clientY }) } render() { return <div onMouseMove={this.handleMouse}> {/*2、参数为组件*/} {/*6将获取到的坐标传递给目标组件*/} <Comp x={this.state.x} y={this.state.y}/> </div> } }}// 7、目标组件,主要作用是渲染显示坐标class Show extends Component{ constructor(props) { super(props); } render() { return <div> <h2>x:{this.props.x}</h2> <h2>x:{this.props.y}</h2> </div> }}// 8、将目标组件传递进入高阶组件,得到组件,此时新组件具有了获取鼠标坐标的能力let NewComponent = HOC(Show);export default NewComponent;



显示结果:


阅读最终代码,我们发现,在构造目标组件时,这个组件需要接收高阶组件获取的鼠标坐标,而获取坐标后我们将其做简单展示。


这里也可以根据这个坐标做一些其他的功能。比如根据坐标移动dom元素,那么就只需要构造一个新的组件,这个组件接收x,y坐标,然后根据坐标移动dom元素,最终代码如下:


import React,{Component} from 'react';// 1、定义一个函数// 2、参数为组件function HOC(Comp){    //3、调用后,返回一个组件    return class extends Component{        constructor(props) {            super(props);            //4、保存鼠标坐标位置            this.state = {                x:0,                y:0            }        }        //5、鼠标移动获取新的位置坐标        handleMouse =(e)=>{            this.setState({                x:e.clientX,                y:e.clientY            })        }        render() {            return <div onMouseMove={this.handleMouse}>                {/*2、参数为组件*/}                {/*6将获取到的坐标传递给目标组件*/}                <Comp x={this.state.x} y={this.state.y}/>            </div>        }    }}// 7、定于目标组件,接收x,y坐标参数function Move({x,y}){    return <div style={{        height:"100px",        width:"100px",        background:"yellow"    }}>        <div            style={{                background:"red",                height:"10px",                width:"10px",                position:"absolute",                left:x,                top:y            }}        >            Move        </div>    </div>}//8、构造新的组件let NewComponent = HOC(Move);export default NewComponent;


案例完成了,总结一下:

1、高阶组件的本质就是一个函数

2、函数的参数为一个组件,通常这个组件会接收高阶组件传入的参数

3、函数调用后返回一个新的组件

4、高阶组件内部主要是将通用的功能逻辑抽离出来


高阶组件还有一些不足,比如说高阶组件存在组件嵌套的问题,我们在下篇文章用一种新的方法来代替他。


以上便是高阶组件的使用方式,当然高阶组件还有好多其他的用法,如果你有什么其他的想法或建议,欢迎留言。

本文分享自微信公众号 - nodejs全栈开发(geekclass)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!