reactの親コンポーネントがサブコンポーネントを呼び出す方法

5173 ワード

1.refを直接使用して取得する
  
import React, {Component} from 'react';

export default class Parent extends Component {
    render() {
        return(
            
) } onRef = (ref) => { this.child = ref } click = (e) => { this.child.myName() } } class Child extends Component { componentDidMount(){ this.props.onRef(this) } myName = () => alert('xiaohesong') render() { return ('woqu') } }

  
2.サブコンポーネントが上位コンポーネントである場合、refによりサブコンポーネントインスタンスメソッドを取得します.
 
  • サブコンポーネントは、propsによって解決される親コンポーネントの情報を取得する必要がある.
  • 親コンポーネントは、refによって解決されるサブコンポーネントの情報を知る必要がある.

  • ここでは後者に属するが、特にサブアセンブリが@connect @withRouterで包まれたコンポーネント(実際にはほとんどのコンポーネントがこの2つに包まれている)のような高次コンポーネントであることに特化している.具体的な例は以下の通りである.
    @withRouter
    export default class childComponent extends Component {
      constructor(props) {
        super(props);
        this.state = {};
      }
      render() {
        return (
    this is childComponent
    ) } } @withRouter export default class parentComponent extends Component { constructor(props) { super(props); this.state = {}; } render () { return { this.childCp = v; }}/> } }

      
    上のchildComponentがwithRouterに包まれた後、parentComponentrefで取得したのはchildComponentではなく、withRouterコンポーネントです.これは気まずいですが、ほとんどの場合、自分が書いたコンポーネントのインスタンスを取得する必要があります.refによって取得されたのはchildComponentではなく、原理的には正しいが、childComponentコンポーネントであれば問題があり、倫理に反して知っている.
    公式に提供されたrefでは、私たちが望んでいるrefを取得できない以上、refで取得したものは何なのかよく考えてみましょう.Javascript言語のレベルに戻ってみると、それはコンポーネントのthisではないでしょうか.
    @withRouter
    export default class childComponent extends Component {
      constructor(props) {
        super(props);
        this.state = {}; //             this  
      }
      render() {
        return (
    this is childComponent
    ) } }

      
    私たちが何を得る必要があるかを知っていれば、それはやりやすいです.私はchildComponentpropを伝えて、このthisをgetすればいいのではないでしょうか.例えば、getInstanceを使っています.
    @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 (
    this is childComponent
    ) } } @withRouter export default class parentComponent extends Component { constructor(props) { super(props); this.state = {}; } render () { return ( { this.childCpWrapper = withRouter; }} // `withRouter` , , getInstance={(childCp) => { this.childCp = childCp; }} // `getInstance` `childComponent` /> ); } }

      
    perfect ! 問題は解決しました.このようにして、私はどのように高次コンポーネントを使っても、どのようにして私たちのchildComponentを包んでも、私たちはgetInstanceを通じて、千山万水を通り抜けて直接childComponentの例を得ることができます.
    もちろん完璧でも相対的であり、例えば上記のスキームでは、childComponentの構造関数ごとにthisを暴露したコードを書かなければなりません.面倒で、苦労します.withRefのようなHOCを書くことができます
    //      , `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,
          };
          //     getInstance   ref,
          //   `WrappedComponent`,   getInstance    `WrappedComponent`  
          //       [yangshenghaha]     
          props.ref = (el)=>{
              this.props.getInstance && this.props.getInstance(el);this.props.ref && this.props.ref(el);
          }
          return (
            
          );
        }
      };
    };
    

       withRefを使って
    @withRouter
    @withRef  //            ,  :         `childComponent`   
    export default class childComponent extends Component {
      constructor(props) {
        super(props);
        this.state = {};
      }
      render() {
        return (
    this is childComponent
    ) } } @withRouter export default class parentComponent extends Component { constructor(props) { super(props); this.state = {}; } render () { return ( { this.childCpWrapper = withRouter; }} // `getInstance` `childComponent` getInstance={(childCp) => { this.childCp = childCp; }} /> ); } }

      
    転載先:https://www.cnblogs.com/jcxfighting/p/10512005.html