獲取react中高階組件方法


什么是高階組件?

高階組件就是接受一個組件作為參數並返回一個新組件的函數。這里需要注意高階組件是一個函數,並不是組件,這一點一定要注意。同時這里強調一點高階組件本身並不是 React API。它只是一種模式,這種模式是由React自身的組合性質必然產生的。更加通俗的講,高階組件通過包裹(wrapped)被傳入的React組件,經過一系列處理,最終返回一個相對增強(enhanced)的 React 組件,供其他組件調用。

react中獲取的ref是什么?

  • 如果ref寫在組件上,那么獲取的是 組件的實例對象;
  • 如果ref寫在組件內的標簽上(div,span等),獲取的相應的DOM節點那么可知本文中獲取的高階組件的ref所指的是組件的實例對象即 子組件的this

獲取方式:

@withRouter
export default class childComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {};
    const { getInstance } = props;
    if (typeof getInstance === 'function') {
      getInstance(this); // 在這里把this暴露給`parentComponent`
    }
  }
  render() {
    return (<div>this is childComponent</div>)
  }
}
@withRouter
export default class parentComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {}; 
  }
  render () {
    return (
     <childComponent 
       ref={(withRouter) => { this.childCpWrapper = withRouter; }}  // 這里獲取的是`withRouter`組件,一般沒啥用,這里寫出來只是為了對比
       getInstance={(childCp) => { this.childCp = childCp; }} // 這里通過`getInstance`傳一個回調函數接收`childComponent`實例即可
    />
    );
  }
 }

下面將上面的方法優化一下,單獨寫一個類來獲取

// 只做一件事,把`WrappedComponent`回傳個`getInstance`(如果有的話)
export default (WrappedComponent) => {
  return class withRef extends Component {
    static displayName = `withRef(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`;
    render() {
      // 這里重新定義一個props的原因是:
      // 你直接去修改this.props.ref在react開發模式下會報錯,不允許你去修改
      const props = {
        ...this.props,
      };
      const { getInstance } = props;
      if (typeof getInstance === 'function') {
        // 在這里把getInstance賦值給ref,
        // 傳給`WrappedComponent`,這樣就getInstance能獲取到`WrappedComponent`實例
        props.ref = getInstance;
      }
      return (
        <WrappedComponent {...props} />
      );
    }
  };
};

// 如何使用?
@withRouter
@withRef  // 這樣使用是不是方便多了,注意:這句必須寫在最接近`childComponent`的地方
export default class childComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  render() {
    return (<div>this is childComponent</div>)
  }
}
@withRouter
export default class parentComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {}; 
  }
  render () {
    return (
     <childComponent 
       // 這里獲取的是`withRouter`組件,一般沒啥用,這里寫出來只是為了對比
       ref={(withRouter) => { this.childCpWrapper = withRouter; }}  
      // 這里通過`getInstance`傳一個回調函數接收`childComponent`實例即可
       getInstance={(childCp) => { this.childCp = childCp; }} 
    />
    );
  }
 }


免責聲明!

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



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