博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【译】三分钟掌握 React 高阶组件
阅读量:6415 次
发布时间:2019-06-23

本文共 3596 字,大约阅读时间需要 11 分钟。

掌握这个有用的模式,停止在
React Components 中重复逻辑! ?

原文:

作者:Jhey Tompkins
译者:博轩

什么是高阶组件?

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

译注:对,我又一次借鉴了官网 ?

它做了什么?

他们接收一个组件并返回一个新的组件!

什么时候去使用?

当你的组件之间出现重复的模式 / 逻辑的时候。

栗子:

  • 挂载,订阅数据
  • UI 增加交互(也可以使用容器组件,或者 )
  • 排序,过滤输入的数据
译注:第三个说法,我个人可能更加倾向于在传入组件之前做处理,而不是使用高阶组件

一个愚蠢的例子

我们有一个 Mouse 组件。

const Mouse = () => (    ?)复制代码

接下来,让我们使用 模块,来让组件变的可以拖拽。

class Mouse extends Component {    componentDidMount = () => new Draggable(this.ELEMENT)    render = () => (         (this.ELEMENT = e)} role="img">?    )}复制代码

我们加一只 ?

const Cat = () => (    ?)复制代码

这个组件同样需要变得可拖拽✋,接下来,让我们使用高阶组件(HOC)来试一下:

const withDrag = Wrapped => {    class WithDrag extends Component {        componentDidMount = () => new Draggable(this.ELEMENT)        render = () => {            return (                 (this.ELEMENT = e)}>                    
) } } WithDrag.displayName = `WithDrag(${
Wrapped.displayName || Wrapped.name})` return WithDrag;}复制代码

我们的高阶组件(HOC)可以通过 props 接受一组件,并返回一个新的组件。

许多高阶组件会在传递组件的过程中,注入新的 props 。这通常是决定我们是否应该使用高阶组件的因素之一。如果,我们不注入 props ,我们可以使用一个容器组件,或者 。

对于我们的高阶组件(HOC),我们也可以使用 来达到相同的效果。你可能会觉得使用 HOC 来实现并不合适。但是,这个 “愚蠢的例子” 会让你更加熟悉 HOC 。 这比注入数据的示例更加有趣!?

让我们将这个 HOC 应用到 CatMouse 组件上吧 ?

const Mouse = () => (    ?)const Cat = () => (    ?)const DraggableMouse = withDrag(Mouse)const DraggableCat = withDrag(Cat)class App extends Component {    render = () => (        
)}复制代码

接下来,让我们在高阶组件中增加 onDrag 回调函数,并在 props 中注入 xy 的位置属性。

const withDrag = Wrapped => {    class WithDrag extends Component {        state = {            x: undefined,            y: undefined,        }        componentDidMount = () => new Draggable(this.ELEMENT, { onDrag: this.onDrag })        onDrag = e => {            const { x, y } = e.target.getBoundingClientRect();            this.setState({ x: Math.floor(x), y: Math.floor(y) })        }        render = () => (             (this.ELEMENT = e)}>                
) } WithDrag.displayName = `WithDrag(${Wrapped.displayName || Wrapped.name})` return WithDrag;}复制代码
const Mouse = () => (            ?        {x !== undefined &&             y !== undefined && (                 {`(${x}, ${y})`}         )}    )复制代码

现在 Mouse 组件会向用户展示他的 XY 位置属性 ?

我们也可以给 HOC 传递 props。然后在传递的过程中过滤掉这些无用的属性。举个例子,传递一个 onDrag 回调函数。

const withDrag = Wrapped => {    class WithDrag extends Component {        componentDidMount = () => new Draggable(this.ELEMENT, { onDrag: this.props.onDrag })        render = () => {            const { onDrag, ...passed } = this.props;            return (                 (this.ELEMENT = e)}>                    
) } } WithDrag.displayName = `WithDrag(${
Wrapped.displayName || Wrapped.name})` return WithDrag;}class App extends Component { render = () => (
console.info(e.target.getBoundingClientRect())} />
)}复制代码

通过使用 HOC ,我们的组件仍然很简单,复杂的逻辑都交给 HOC 来处理了。 我们的组件只关心传递给他们的内容。 我们可以在其他地方重复使用它们而且不会有可以被拖拽的属性。这使得我们的应用更容易维护。

优秀的实践 ?

  • 当出现重复的模式的时候,使用它们
  • 为了方便调试,需要更新处理之后组件的 displayName
  • 传递与当前 HOC 无关的所有 props

糟糕的实践 ?

  • 过度使用,其他模式可能会更加适合
  • 改变原始组件
  • render 方法中使用高阶组件
译注:永远不要在
React render() 方法中定义
React 组件(甚至是无状态组件)。
React 在每次更新状态的时候,都会废弃旧的
html DOM 元素并将其替换为全新的元素。比如在
render() 函数中定义一个输入组件,元素被替换之后就会失去焦点,每次只能输入一个字符。

注意 ?

  • Refs 不会被传递
  • 务必复制静态方法
  • 大部分 HOC 都可以和 render props 相互替换使用

这就是一篇关于高阶组件的简短介绍 ~

官方文档:

本文已经联系原文作者,并授权翻译,转载请保留原文链接

转载于:https://juejin.im/post/5cdcd834f265da0356325846

你可能感兴趣的文章
django ajax提交 Forbidden CSRF token missing
查看>>
maven常见异常
查看>>
shell基础一
查看>>
windows下查看端口占用情况
查看>>
轻松玩转window7之五:管理共享
查看>>
邮件服务器搭建,可连接客户端
查看>>
大数据时代的遨游
查看>>
大数据测试之hadoop单机环境搭建(超级详细版)
查看>>
我的友情链接
查看>>
CSS教程:div垂直居中的N种方法[转]
查看>>
不要做浮躁的嵌入式系统工程师
查看>>
linux 文件操作与目录操作
查看>>
解决IE6浏览器下position:fixed固定定位问题
查看>>
KMP串匹配算法解析与优化
查看>>
css3动画简介以及动画库animate.css的使用
查看>>
javascript DOM节点操作
查看>>
c++ invoke java in android
查看>>
meta 之 viewport
查看>>
Linux下文件 ~/.bashrc 和 ~/.bash_profile 和 /etc/bashrc 和 /etc/profile 的区别 | 用户登录后加载配置文件的顺序...
查看>>
关于在swiper轮播组件中使用echarts的'click'事件无效
查看>>