React系列之高阶组件

落落落洛克 等级 552 0 0

我的前端学习笔记📒

最近花了点时间把笔记整理到语雀上了,方便童鞋们阅读

React系列之高阶组件

React系列之高阶组件

背景

用到的原因是因为公司最近要做一个钉钉oa系统,选的技术栈则是比较火热的react,开发中遇到的问题就是代码如何复用问题,因为react官方已经不推荐使用Mixins,而是推荐了高阶组件这种方式,接下来我们就来聊聊它

高阶组件的概念

a higher-order component is a function that takes a component and returns a new component.

意思是:高阶组件是一个函数,它接受一个组件并返回一个新组件

利用函数带你理解高阶组件

举个例子🌰:假设我们现在需要实现一个登陆注册功能,为了方便,我们把用户(user)存在localStorage下,如果发生操作行为就会先去检测下有没有user (当然现实开发不可以这样做的)

代码实现:

// 登陆
  function login() {
    let user = localStorage.getItem('user');
    console.log('login ' + login);
}
// 注册
function resgister() {
    let user = localStorage.getItem('user');
    console.log('resgister ' + user);
}

login();
resgister();

上面的例子我们发现都有一句一模一样的冗余代码,这显然对于有代码洁癖的人简直不能忍,那就动手将它抽离出来挨打吧

代码实现:

// 登陆
  function login() {
    console.log('login ' + login);
}
// 注册
function resgister() {
    console.log('resgister ' + user);
}
// 抽离出来的中间函数
function wrapUser(Wrapfunc) {
    let Newfunc = () => {
       let user = localStorage.getItem('user');
       Wrapfunc(user);
    };
    return Newfunc;
}
// 调用
login = wrapUser(login);
resgister = wrapUser(resgister);
login();
resgister();

以上的例子我们可以把wrapUser称为高阶函数,它负责的是就是把我们共用代码抽离的出来,这样简化了复用的代码,很多同学会问,上面的代码量不是更加多了吗?但是实际开发项目时候复用的代码可不是这么一丁点,还有可能有其他需求产生复用这段代码就比如产品临时加了需要忘记密码的功能

代码如下:

 function forgetPassWord(){
    console.log('forgetPassWord ' + user);
 }
 forgetPassWord = wrapUser(forgetPassWord);
 forgetPassWord()

从高阶函数来看高阶组件

上面的代码如果用react方式是怎么实现的

Login组件

import React, {Component} from 'react'
class Login extends Component {
    constructor(props) {
        super(props);
        this.state = {
            user: ''
        }
    }

    componentWillMount() {
        let user = localStorage.getItem('user');
        this.setState({
            user
        })
    }

    render() {
        return (
            <div>login{this.state.user}</div>
        )
    }
}

export default Login;

Register组件

import React, {Component} from 'react'
class Register extends Component {
    constructor(props) {
        super(props);
        this.state = {
            user: ''
        }
    }
    componentWillMount() {
        let user = localStorage.getItem('user');
        this.setState({
            user
        })
    }
    render() {
        return (
            <div>register{this.state.user}</div>
        )
    }
}

export default Register;

可以看到这个组件这两个组件都有复用的代码,所以我们上述高阶函数wrapUser的例子来实现高阶组件

WrapUser高阶组件

import React, {Component} from 'react'

export default (WrapComponent) => {
    // 这里的WrapComponent是我们传进来的组件
    class NewComponent extends Component {
        constructor() {
            super();
            this.state = {
                user: ''
            }
        }

        componentWillMount() {
            let user = localStorage.getItem('user');
            this.setState({
                user
            })
        }

        render() {
            return <WrapComponent user={this.state.user}/>
        }
    }

    return NewComponent
}

上述的代码是声明一个函数这个函数从参数是接收一个组件,然后return回去一个新的组件,咋一看有同学发现这个很像是父组件套了一个子组件,没错实际上就是这样的,而且他们的通信也是父子组件通信

这样我们来简化下login组件和register组件

Login组件

import React, {Component} from 'react';
import WrapUser from 'WrapUser';

class Login extends Component {

    render() {
        return (
            <div>login{this.props.user}</div>
        )
    }
}

Login = WrapUser(Login);

export default Login;

Register组件

import React, {Component} from 'react';
import WrapUser from 'WrapUser';

class Register extends Component {

    render() {
        return (
            <div>register{this.props.user}</div>
        )
    }
}

Register = WrapUser(Register);

export default Register;

到这里我们代码复用性的问题就解决了,高阶组件实际就是一个函数,并不要被它的名称所吓倒

总结

  • 高阶组件的目的就是为了解决代码复用性问题
  • 高阶组件的通信是按照父子通信机制的

我的前端学习笔记📒

最近花了点时间把笔记整理到语雀上了,方便童鞋们阅读

React系列之高阶组件

React系列之高阶组件

收藏
评论区

相关推荐

为什么 React 源码不用 TypeScript 来写?
周末的,看点轻松的吧,之前看过 React 的源码,比较好奇像 React 这样庞大的工程为什么没有用 TypeScript。 Facebook 工程师 Cat Chen 在知乎上(https://www.zhihu.com/question/378470381/answer/1079675543(https://www.zhihu.com/quest
2020年值得你去试试的10个React开发工具
2020年值得你去试试的10个React开发工具 2020年值得你去试试的10个React开发工具 本文由葡萄城技术团队翻译并首发 转载请注明出处:葡萄城官网(https://www.
25、react入门教程
25、react入门教程 25、react入门教程 0. React介绍 0.1 什么是React? React(有时称为React.js 或ReactJS)是一
Angular vs React 最全面深入对比
Angular vs React 最全面深入对比 Angular vs React 最全面深入对比 本文参考文章:https://www.sitepoint.com/reactvsangul
Create React App
Create React App Create React App Facebook开源了React前端框架(MIT Licence),也同时提供了React脚手架 createreactapp(ht
React系列之高阶组件
我的前端学习笔记📒 最近花了点时间把笔记整理到语雀上了,方便童鞋们阅读 我的前端学习笔记📒(https://www.yuque.com/wanggangfeng
做了N+1个企业项目之后, 我总结了这些React必备插件
为了提高大家开发 React 项目的效率, 笔者结合自己的实际工作经验, 汇总如下React项目常用插件. 1. 状态管理 Redux JavaScript 状
做了N+1个企业项目之后, 我总结了这些React必备插件
为了提高大家开发 React 项目的效率, 笔者结合自己的实际工作经验, 汇总如下React项目常用插件. 1. 状态管理 Redux JavaScript 状
Hook 简介 – React
Hook 简介 _Hook_ 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。 import React, { useState } from 'react'; function Example() { // 声明一个新的叫做 “count” 的 sta
Hook 规则 – React
Hook 规则 _Hook_ 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。 Hook 本质就是 JavaScript 函数,但是在使用它时需要遵循两条规则。我们提供了一个 linter 插件(https://www.npmjs.com/package/
使用 State Hook – React
使用 State Hook_Hook_ 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。中使用下面的例子介绍了 Hook:import React, { useState } from 'react';function Example() { //
Hook 规则 – React
Hook 规则_Hook_ 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。Hook 本质就是 JavaScript 函数,但是在使用它时需要遵循两条规则。我们提供了一个 来强制执行这些规则: 只在最顶层使用 Hook不要在循环,条件或嵌套函数中调用 Hoo
React 之源码概览
本节将对 React 的源码架构,约定及其实现进行概述。如果您想 的开发,我们希望这份指南可以帮助你更加轻松地进行修改。我们并不推荐在 React 应用中遵循这些约定。有许多约定是历史原因,并且之后也许会有所修改。 项目根目录当克隆 之后,你们将看到项目根目录的信息: 包含元数据(比如 package.json)和 React 仓库中所有
React 之Virtual DOM 及内核
什么是 Virtual DOM?Virtual DOM 是一种编程概念。在这个概念里, UI 以一种理想化的,或者说“虚拟的”表现形式被保存于内存中,并通过如 ReactDOM 等类库使之与“真实的” DOM 同步。这一过程叫做。这种方式赋予了 React 声明式的 API:您告诉 React 希望让 UI 是什么状态,React 就确保 DOM 匹
如何在React Native和Expo中掩盖Text和TextInput组件
在本文中,我将向您展示如何在React Native和Expo中使用自定义蒙版,可用于iOS,Android和Web!我们将使用一个名为库,这是一个没有本机代码的完整javascript库,然后您可以在React Native环境的所有CLI中使用。](https://res.cloudinary.com/practicaldev/image/fetch/s