跳至主要內容

1. 什么是高阶组件

Mr.He大约 2 分钟

高阶组件

1. 什么是高阶组件

高阶组件就是一个函数,传给它一个组件,它返回另一个新组件。

const NewComponent = heightOrderComponent(OldComponent)

NewComponent 会使用传给它的组件作为子组件。

简单例子:

import React, { Component } from 'react'

export default (WrappedComponent) => {
    class NewComponent extends Component {
        //...
        render () {
            return <WrappedComponent />
        }
    }
    return NewComponent
}

在高阶组件中添加一些数据启动工作:

import React, { Component } from 'react'

export default (WrappedComponent, name) => {
  class NewComponent extends Component {
    constructor () {
      super()
      this.state = { data: null }
    }

    componentWillMount () {
      let data = localStorage.getItem(name)
      this.setState({ data })
    }

    render () {
      return <WrappedComponent data={this.state.data} />
    }
  }
  return NewComponent
} 

NewComponent 根据第二个参数name从LocalStorage中加载数据,并在渲染的时候将 state.data 通过 props.data 传给 WrappedComponent。

2. 高阶组件怎么用

假设上面的高阶组件存放在 src/wrapWithLoadData.js 文件中

1. 使用第一次

import wrapWithLoadData from './wrapWithLoadData'

class InputWithUserName extends Component {
    render () {
        return <input value={this.props.data} />
    }
}

InputWithUserName = wrapWithLoadData(InputWithUserName, 'username')
export default InputWithUserName

可以看出如果想要从LocalStorage里加载 username 字段值作为 <input />的值,通过wrapWIthLoadData可以轻易做到。

别人使用这个组件的时候实际是用了被加工过的组件

最终使用

import InputWithUserName from './InputWithUserName'

class Index extends Component {
  render () {
    return (
      <div>
        用户名:<InputWithUserName />
      </div>
    )
  }
}

2. 使用第二次

再看看下面这个例子,我们又需要一个文本输入框,它需要从LocalStorage加载 content字段的数据。我们只需定义一个新的 TextareaWithContent.

import wrapWithLoadData from './wrapWithLoadData'

class TextareaWithContent extends Component {
  render () {
    return <textarea value={this.props.data} />
  }
}

TextareaWithContent = wrapWithLoadData(TextareaWithContent, 'content')
export default TextareaWithContent

这里我们不需要重复写从LocalStorage加载数据字段的逻辑,直接使用高阶组件包装就可以使用。

3. 高阶组件作用

为了组件之间代码复用。

组件中相同的逻辑抽离出来放到高阶组件中进行复用

高阶组件内部的包装组件和被包装组件之间通过props传递数据