高阶组件

简单来说,高阶组件可以看做一个函数,且该函数接受一个组件作为参数,并返回一个新的组件。

我在之前的博客《闭包和类》中提到一个观点,面向对象的好处就在于,易于理解,方便维护和复用。

其实高阶组件,也是为了更好地复用之前的组件。它可以理解为,基础组件通过包裹处理,生成一个适应某些场景的组件。

它可能存在于以下几种场景:

定制props

一个简单例子:

function withMoreThings(WrappedComponent) {
return class extends React.Component {
render() {
const moreThings = {
more: 'things',
};
return <WrappedComponent {...this.props} ...moreThings/>
}
}
}

这是HOC(High Order Component)最常用的一种方式,用来传递一些定制化的参数给内部组件。

提取公共方法、属性

在to B的项目中,表单是一个大头,所有流程都绕不开表单。也就会说到受控组件和非受控组件。

受控组件

由于HTML表单元素会保留一些内部状态,比如input框,它会有自己内部的状态来保存用户的输入值。

<input type="text" name="name" />

此时,为了能够处理将React的state和表单元素的内部状态统一起来,React提供了一种称为“受控组件”的技术。

class NameInput extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''}; this.handleChange = this.handleChange.bind(this);
} handleChange(event) {
console.log(this);
this.setState({value: event.target.value});
} render() {
return (
<input type="text" value={this.state.value} onChange={this.handleChange} />
);
}
}

通过内部的state和绑定change事件,就可以将input内部的处理机制转移到React的默认处理机制上,收到React的控制。

但是,还是有一些元素,不能使用这种方法,比如

<input type="file">

这个元素是只读的,用户选择完毕后,可以获取到对应的文件。不能通过React内部的state来模拟。

这就引出了——

非受控组件

非受控组件从DOM中获取表单值,而不是通过React的state来处理。由于它不经过React的一些逻辑,所以不能对它的状态做监控。这里有一篇文章Controlled and uncontrolled form inputs in React don't have to be complicated介绍了何时可以使用非受控组件。

下面是一个非受控组件的例子:

import React, { Component } from "react";
export default class NameInput extends Component {
constructor(props) {
super(props);
} handleChange(event) {
console.log(this);
this.setState({ value: event.target.value });
} render() {
return (
<input
type="text"
defaultValue="test"
ref={input => (this.input = input)}
/>
);
}
}
<input type="checkbox"> 和 <input type="radio"> 支持 defaultChecked,<input type="text"><select> 和 <textarea> 支持 defaultValue,可以帮助设置表单默认值。

非受控组件通过ref来获取DOM元素,然后根据当前DOM去更新UI。

有关Ref的使用,参考这个文档Refs & DOM

我个人建议,如果对于一些数据交互较少,展示和处理基本在组件内部完成,不会涉及到很多组件间数据交换的情景,可以使用非受控组件,更快,更直观。其他情况仍然建议使用受控组件,方便数据流的传导。

接着说回高阶组件。在使用表单时,很多情境下的输入,我们都希望统一由state,或者redux来保存,而不是被dom节点存储。

上面讲到了受控组件的使用,关键点有三:

1.对应的onChange方法

2.对应的存储点,state或者redux

3.绑定到对应组件

参考上面的描述,来实现一个高阶组件的生成函数。

这里是一个例子:https://codesandbox.io/s/7p85l213q

这样就可以很方便的生成受控组件。

在一些场景下,我们也可以用其他组件包装WrappedComponent。比如,添加一些小图标,用父组件可能不够灵活,用HOC则可以很轻松地生成一个可配置的组件,灵活许多。

React Higher Order Components in depth还提到一种生成HOC的方法,类继承,改写更彻底。详细内容可以参考这篇文章。也可以查看知乎的这篇翻译深入理解 React 高阶组件

以上,感谢阅读。

react系列(二)高阶组件-HOC的更多相关文章

  1. React中的高阶组件

    高阶组件(HOC, High-Order Component)是React中用于重组组件逻辑的高级技术,是一种编程模式而不是React的api. 直观来讲,高阶组件是以某一组件作为参数返回一个新组件的 ...

  2. 高阶函数 HOF & 高阶组件 HOC

    高阶函数 HOF & 高阶组件 HOC 高阶类 js HOC 高阶函数 HOF 函数作为参数 函数作为返回值 "use strict"; /** * * @author x ...

  3. React中的高阶组件,无状态组件,PureComponent

    1. 高阶组件 React中的高阶组件是一个函数,不是一个组件. 函数的入参有一个React组件和一些参数,返回值是一个包装后的React组件.相当于将输入的React组件进行了一些增强.React的 ...

  4. React: 高阶组件(HOC)

    一.简介 如我们所知,JavaScript有高阶函数这么一个概念,高阶函数本身是一个函数,它会接收或者返回一个函数,进而对该函数进行操作.其实,在React中同样地有高阶组件这么一个东西,称为HOC, ...

  5. 高阶组件 HOC

    一. A higher-order component (HOC) is an advanced technique in React for reusing component logic. a h ...

  6. 高阶函数HOF和高阶组件HOC(Higher Order Func/Comp)

    一.什么是高阶函数(组件),作用是什么? 子类使用父类的方法可以通过继承的方式实现,那无关联组件通信(redux).父类使用子类方法(反向继承)呢 为了解决类(函数)功能交叉/功能复用等问题,通过传入 ...

  7. React进阶之高阶组件

    前言 本文代码浅显易懂,思想深入实用.此属于react进阶用法,如果你还不了解react,建议从文档开始看起. 我们都知道高阶函数是什么, 高阶组件其实是差不多的用法,只不过传入的参数变成了react ...

  8. 函数式编程与React高阶组件

    相信不少看过一些框架或者是类库的人都有印象,一个函数叫什么creator或者是什么什么createToFuntion,总是接收一个函数,来返回另一个函数.这是一个高阶函数,它可以接收函数可以当参数,也 ...

  9. 聊聊React高阶组件(Higher-Order Components)

    使用 react已经有不短的时间了,最近看到关于 react高阶组件的一篇文章,看了之后顿时眼前一亮,对于我这种还在新手村晃荡.一切朝着打怪升级看齐的小喽啰来说,像这种难度不是太高同时门槛也不是那么低 ...

随机推荐

  1. Spring课程 Spring入门篇 5-7 advisors

    1 简析 1.1 advisor简析(这个不太明白,后续再看吧) 2 代码演练 2.1 环绕通知的综合应用(代码和视频对不上,慕课网讲的本身有问题)       1 简析 1.1 advisor简析( ...

  2. Java CAS总结

    文章目录 1. CPU指令对CAS的支持(CPU的cas指令是原子的) 或许我们可能会有这样的疑问,假设存在多个线程执行CAS操作并且CAS的步骤很多,有没有可能在判断V和E相同后,正要赋值时,切换了 ...

  3. webpack build后生成的app、vendor、manifest三者有何职能不同?

    贴一下之前vue脚手架的webpack3配置: app.js是入口js,vendor则是通过提取公共模块插件来提取的代码块(webpack本身带的模块化代码部分),而manifest则是在vendor ...

  4. 基于Maven的Spring + Spring MVC + Mybatis的环境搭建

    基于Maven的Spring + Spring MVC + Mybatis的环境搭建项目开发,先将环境先搭建起来.上次做了一个Spring + Spring MVC + Mybatis + Log4J ...

  5. Csharp: speech to text, text to speech in win

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  6. struts1 & jquery form 文件异步上传

    1.概述 还在用struts1?是的,在地球的没写地方,落后的生产方式还在运转(老项目). 从 继承org.apache.struts.action.Action, 继承org.apache.stru ...

  7. NOIP2017:逛公园

    Sol 发现\(NOIP2017\)还没\(AK\)??? 赶紧改 考场上明明打出了\(DP\),没时间了,没判环,重点是没初始化数组,爆\(0\) \(TAT\) 先最短路,然后\(f[i][j]\ ...

  8. 原生js操作DOM基础-笔记

    原文参考http://mp.weixin.qq.com/s?__biz=MzU3MDA0NTMzMA==&mid=2247485490&idx=1&sn=15197b4b53e ...

  9. web前端优化之内容优化

    前端内容优化主要有以下几条: 1.尽量减少http请求 (1)合并文件,把多个css文件合并在一起: (2)css Sprites,把css相关的background元素进行背景图绝对定位: (3)图 ...

  10. 【热门活动】开年好运开门来!送祝福,赢iPad

    羊年新的云端征程起航,阿里云邀请了众多云上客户给大家送祝福啦,听听他们的寄语,用云计算增强你的竞争力,一起赢在云端! 想赢iPad吗?参与我们的微博活动,和大家一起送上云端祝福,就有机会把iPad带回 ...