14
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

React > 親から子のメソッドを呼ぶ

Last updated at Posted at 2021-06-24

子の中にあるgetAlertメソッドを親から呼びたい時のサンプル

修正:RefForwardingComponentdeprecatedだったので、ForwardRefRenderFunctionに変更

/**
 * @deprecated Use ForwardRefRenderFunction. forwardRef doesn't accept a
 *             "real" component.
 */
interface RefForwardingComponent <T, P = {}> extends ForwardRefRenderFunction<T, P> {}

PropsにInterfaceを使わない場合

子 (Child.tsx)

Child.tsx
import React, { forwardRef, useImperativeHandle } from "react";

// 公開したいメソッドの定義
export interface ChildHandles {
  getAlert(): void;
}

// コンポーネントを `forwardRef` でラップする必要があります。
export const Child = forwardRef<ChildHandles>((props, ref) => {
  // コンポーネントのインスタンスが拡張されます
  // 第2引数として渡されたコールバックから返されたもので拡張されます
  useImperativeHandle(ref, () => ({
    getAlert() {
      alert("getAlert from Child");
    }
  }));

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

親 (Parent.tsx)

Parent.tsx
import React, { useRef } from "react";
import { Child, ChildHandles } from "./Child";

export const Parent = () => {
  // 子コンポーネントのインスタンスにアクセスするためには、`ref` に割り当てる必要があります。
  const childRef = useRef<ChildHandles>(null);

  const onClick = () => {
    childRef.current?.getAlert();
  };

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

codesandboxにサンプルをあげてます

PropsにInterfaceを指定したい場合

子 (Child.tsx)

Child.tsx
import React, {
  forwardRef,
  useImperativeHandle,
  ForwardRefRenderFunction
} from "react";

// 公開したいメソッドの定義
export interface ChildHandles {
  getAlert: () => void;
}

export interface ChildProps {
  firstName: string;
  lastName: string;
}

const ChildComponent: ForwardRefRenderFunction <ChildHandles, ChildProps> = (
  props,
  ref
) => {
  // コンポーネントのインスタンスが拡張されます
  // 第2引数として渡されたコールバックから返されたもので拡張されます
  useImperativeHandle(ref, () => ({
    getAlert() {
      alert("we love " + props.firstName + " " + props.lastName + " !!");
    }
  }));

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

// コンポーネントを `forwardRef` でラップする必要があります。
export const Child = forwardRef(ChildComponent);

親 (Parent.tsx)

Parent.tsx
import React, { useRef } from "react";
import { Child, ChildHandles } from "./Child";

export const Parent = () => {
  // 子コンポーネントのインスタンスにアクセスするためには、`ref` に割り当てる必要があります。
  const childRef = useRef<ChildHandles>(null);

  const onClick = () => {
    childRef.current?.getAlert();
  };

  return (
    <div>
      <Child firstName="eric" lastName="martin" {...{}} ref={childRef} />
      <button onClick={onClick}>Click</button>
    </div>
  );
};

codesandboxにサンプルをあげてます

以上

参考

14
11
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?