1. ホーム
  2. javascript

[解決済み] 親メソッドから子メソッドを呼び出す

2022-03-25 14:21:37

質問

2つのコンポーネントがあります。

  1. 親コンポーネント
  2. 子コンポーネント

ParentからChildのメソッドを呼び出そうとして、この方法を試したのですが、結果を得ることができませんでした。

class Parent extends Component {
  render() {
    return (
      <Child>
        <button onClick={Child.getAlert()}>Click</button>
      </Child>
      );
    }
  }

class Child extends Component {
  getAlert() {
    alert('clicked');
  }
 
  render() {
    return (
      <h1 ref="hello">Hello</h1>
    );
  }
}

ParentからChildのメソッドを呼び出す方法はありますか?

注:ChildとParentのコンポーネントは2つの異なるファイルにあります。

解決方法は?

まず最初に、これは一般的に表現すると ではなく Reactの土地で物事を進めていく方法です。通常、あなたがしたいことは、propsで子へ機能を伝え、eventで子からの通知を受け取ることです(もっといい方法はあります。 dispatch ).

しかし、もしあなたが しなければならない 子コンポーネントで命令型メソッドを公開するには レフ . これは逃げ道であり、通常はより良い設計が可能であることを意味することを覚えておいてください。

以前は、参照はクラスベースのコンポーネントにのみサポートされていました。 の出現により React Hooks そのようなことはもうありません。

フックを使ったモダンなReact ( v16.8+ )

const { forwardRef, useRef, useImperativeHandle } = React;

// We need to wrap component in `forwardRef` in order to gain
// access to the ref object that is assigned using the `ref` prop.
// This ref is passed as the second parameter to the function component.
const Child = forwardRef((props, ref) => {

  // The component instance will be extended
  // with whatever you return from the callback passed
  // as the second argument
  useImperativeHandle(ref, () => ({

    getAlert() {
      alert("getAlert from Child");
    }

  }));

  return <h1>Hi</h1>;
});

const Parent = () => {
  // In order to gain access to the child component instance,
  // you need to assign it to a `ref`, so we call `useRef()` to get one
  const childRef = useRef();

  return (
    <div>
      <Child ref={childRef} />
      <button onClick={() => childRef.current.getAlert()}>Click</button>
    </div>
  );
};

ReactDOM.render(
  <Parent />,
  document.getElementById('root')
);
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>

<div id="root"></div>

のドキュメント useImperativeHandle() こちら :

useImperativeHandle を使用する際に、親コンポーネントに公開されるインスタンス値をカスタマイズします。 ref .

クラスコンポーネントによるレガシーAPI ( >= [email protected] )

const { Component } = React;

class Parent extends Component {
  constructor(props) {
    super(props);
    this.child = React.createRef();
  }

  onClick = () => {
    this.child.current.getAlert();
  };

  render() {
    return (
      <div>
        <Child ref={this.child} />
        <button onClick={this.onClick}>Click</button>
      </div>
    );
  }
}

class Child extends Component {
  getAlert() {
    alert('getAlert from Child');
  }

  render() {
    return <h1>Hello</h1>;
  }
}

ReactDOM.render(<Parent />, document.getElementById('root'));
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<div id="root"></div>

コールバック参照API

コールバックスタイルの参照は、最近のReactではそれほど一般的ではありませんが、これを実現するためのもう一つのアプローチです。

const { Component } = React;
const { render } = ReactDOM;

class Parent extends Component {
  render() {
    return (
      <div>
        <Child ref={instance => { this.child = instance; }} />
        <button onClick={() => { this.child.getAlert(); }}>Click</button>
      </div>
    );
  }
}

class Child extends Component {
  getAlert() {
    alert('clicked');
  }

  render() {
    return (
      <h1>Hello</h1>
    );
  }
}


render(
  <Parent />,
  document.getElementById('app')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="app"></div>