獲取react中高階組件方法

什麼是高階組件?

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

react中獲取的ref是什麼?

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

獲取方式:java

@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`實例便可
    />
    );
  }
 }

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

// 只作一件事,把`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; }} 
    />
    );
  }
 }
相關文章
相關標籤/搜索