react:高階組件wrappedComponent


什么是高階組件?

高階部件是一種用於復用組件邏輯的高級技術,它並不是 React API的一部分,而是從React 演化而來的一種模式。 具體地說,高階組件就是一個接收一個組件並返回另外一個新組件的函數!

解決什么問題?

隨着項目越來越復雜,開發過程中,多個組件需要某個功能,而且這個功能和頁面並沒有關系,所以也不能簡單的抽取成一個新的組件,但是如果讓同樣的邏輯在各個組件里各自實現,無疑會導致重復的代碼。比如頁面有三種彈窗一個有title,一個沒有,一個又有右上角關閉按鈕,除此之外別無它樣,你總不能整好幾個彈窗組件吧,這里除了tilte,關閉按鈕其他的就可以做為上面說的基本材料。

高階組件總共分為兩大類

  • 代理方式

  1. 操縱prop

  2. 訪問ref(不推薦)

  3. 抽取狀態

  4. 包裝組件

  • 繼承方式

  1. 操縱生命周期

  2. 操縱prop

代理方式之 操縱prop

import React from 'react'
function HocRemoveProp (WrappedComponent) {
  return class WrappingComPonent extends React.Component{
    render() {
      const { user, ...otherProps } = this.props;
      return <WrappedComponent {...otherProps} />
    }
  }
}
export default HocRemoveProp;
增加prop

接下來我把簡化了寫法,把匿名函數去掉,同時換成箭頭函數

import React from 'react'
const HocAddProp = (WrappedComponent,uid) =>
  class extends React.Component
 {
    render() {
      const newProps = {
        uid,
      };
      return <WrappedComponent {...this.props}  {...newProps}  />
    }
  }
export default HocAddProp;

兩個高階組件的使用方法:

  1. const  newComponent = HocRemoveProp(SampleComponent);

  2. const  newComponent = HocAddProp(SampleComponent,'1111111');

也可以利用decorator語法糖這樣使用

import React, { Component } from 'React';

@HocRemoveProp
class SampleComponent extends Component {

    render() {}
}
export default SampleComponent;

代理方式之 抽取狀態

將所有的狀態的管理交給外面的容器組件,這個模式就是 抽取狀態 外面的容器就是這個高階組件

const HocContainer = (WrappedComponent) =>
  class extends React.Component{
    constructor(props) {
      super(props)
      this.state = {
        name: ''
      }
    }
    onNameChange = (event) => {
      this.setState({
        name: event.target.value
      })
    }
    render() {
      const newProps = {
        name: {
          value: this.state.name,
          onChange: this.onNameChange
        }
      }
      return <WrappedComponent {...this.props} {...newProps} />
    }
  }
@HocContainer
class SampleComponent extends React.Component
 {
  render() {
    return <input name="name" {...this.props.name}/>
  }
}

這樣當我們在使用這個已經被包裹的input組件(SampleComponent)時候 它的值就被放在了HocContainer高階組件中,當很多這樣的input組件都用這個HocContainer高階組件時,那么它們的值都將保存在這個HocContainer高階組件中

代理方式之 包裝組件

const HocStyleComponent = (WrappedComponent, style) =>
  class extends React.Component{
    render() {
      return (
        <div style={style}>
          <WrappedComponent {...this.props} {...newProps} />
        </div>
      )
    }
  }
import HocStyleComponent from  './HocStyleComponent';
const colorSytle ={color:'#ff5555'}
const newComponent = HocStyleComponent(SampleComponent, colorSytle);

 

  1. 代理方式下WrappedComponent會經歷一個完整的生命周期,產生的新組件和參數組件是兩個不同的組件,一次渲染,兩個組件都會經歷各自的生命周期

  2. 而在繼承方式下,產生的新組件和參數組件合二為一,super.render只是生命周期中的函數,變成一個生命周期。

繼承方式之 操縱prop

const HOCPropsComponent = (WrappedComponent) =>
  class extends WrappedComponent{
    render() {
      const elementsTree = super.render();
      let newProps = {
        color: (elementsTree && elementsTree.type === 'div') ? '#fff': '#ff5555'
      };
      const props = Object.assign({}, elementsTree.props, newProps)
      const newElementsTree = React.cloneElement(elementsTree,props,elementsTree.props.children)
      return newElementsTree
    }
  }

這樣就傳入了新的props

React.cloneElement( element, [props], [...children])

克隆並返回一個新的 ReactElement ,新返回的元素會保留有舊元素的 props、ref、key,也會集成新的 props。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM