react高阶组件

高阶组件(Higher-Order Components)

http://huziketang.mangojuice.top/books/react/lesson28

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

高阶组件的作用是用于代码复用,可以把组件之间可复用的代码、逻辑抽离到高阶组件当中。新的组件和传入的组件通过 props 传递信息。

使用场景:

有类似的几个组件但是组件内部只有少部分是不同的,它们身上都还有一些公用的方法,并且这些少部分组件组件都还要调用大组件的方法或者访问它的一些数据

如果我们按照组件封装的方法来实现的的话,我们封装一个大组件,然后把不同的小组件传进去,然后通过props把方法传到小组件,通过回调触发,但是这里有一个问题,我们写这几个组件的时候每次都要把大组件写一遍然后把子组件嵌入进去。假如这里我们采用高阶组件来实现的话,我们只需要把公用的方法和数据写到高阶函数返回的组件中,然后把组件传进去就可以了,最后在每个调用这个大组件的地方直接调用这个函数就可以了。

实例:

wrapWithLoadData根据第二个参数 name 在挂载阶段从 LocalStorage 加载数据,并且 setState 到自己的 state.data 中,而渲染的时候将 state.data 通过 props.data 传给 WrappedComponent

import React, { Component } from 'react'

export default (WrappedComponent, name) => {

class wrapWithLoadData 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 wrapWithLoadData

}

调用:

import wrapWithLoadData from './wrapWithLoadData'

class InputWithUserName extends Component {

render ()

{ return <input value={this.props.data} /> }

}

InputWithUserName = wrapWithLoadData(InputWithUserName, 'username')

export default InputWithUserName

如果现在我们需要另外一个文本输入框组件,它也需要 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

最终使用:

import InputWithUserName from './InputWithUserName'

import TextareaWithContent from './TextareaWithContent

class Index extends Component {

render () {

return (

<div> 用户名:<InputWithUserName /> </div>

<div> 内容:<TextareaWithContent /> </div>

)

} }

假设现在我们需求变化了,现在要的是通过 Ajax 加载数据而不是从 LocalStorage 加载数据。我们只需要新建一个 wrapWithAjaxData 高阶组件:

import React, { Component } from 'react'

export default (WrappedComponent, name) => {

class  wrapWithAjaxData  extends Component {

constructor ()

{ super()

this.state = { data: null }

}

componentWillMount () {

ajax.get('/data/' + name, (data) => {

this.setState({ data })

  }) }

render () {

return <WrappedComponent data={this.state.data} />

} }

return  wrapWithAjaxData 

}

其实就是改了一下 wrapWithLoadData 的 componentWillMount 中的逻辑,改成了从服务器加载数据。现在只需要把 InputWithUserName 稍微改一下:

import wrapWithAjaxData from './wrapWithAjaxData'

class InputWithUserName extends Component {

render () {

return <input value={this.props.data} />

} }

InputWithUserName = wrapWithAjaxData(InputWithUserName, 'username')

export default InputWithUserName

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • React进阶之高阶组件 前言 本文代码浅显易懂,思想深入实用。此属于react进阶用法,如果你还不了解react...
    流动码文阅读 1,194评论 0 1
  • render props, 即函数作为子组件 术语 “render prop” 是指一种在 React 组件之间使...
    Never_er阅读 474评论 0 1
  • 在目前的前端社区,『推崇组合,不推荐继承(prefer composition than inheritance)...
    Wenliang阅读 77,764评论 16 124
  • 高阶组件是react应用中很重要的一部分,最大的特点就是重用组件逻辑。它并不是由React API定义出来的功能,...
    叫我苏轼好吗阅读 933评论 0 0
  • 高阶组件本质是函数,参数是 组件1 返回组件2,高阶组件是为了复用通用逻辑高阶组件eg:import React,...
    GC风暴阅读 246评论 0 0