原文: How to Pass Data and Events Between Components in React
API エンドポイントを利用する CRUD 操作を実装しようとすると、複数のコンポーネントにまたがるデータ管理の難しさに気付くでしょう。
あるいはモーダルを異なるコンポーネントからトリガーしたいこともあるでしょう。
そのような場合の対応方法は、なかなか理解が難しいかもしれません。
このチュートリアルでその方法を解説します。
親コンポーネントから子コンポーネントにデータを受け渡す方法
はじめに、親コンポーネントと子コンポーネントの間でデータを受け渡す場合を考えます。
まず、親と子にあたる 2 つのコンポーネントを作成します。
import React from 'react'
export default function Parent() {
return (
<div>
</div>
)
}
import React from 'react'
export default function Child() {
return (
<div>
</div>
)
}
次に、Parent コンポーネントで Child コンポーネントをインポートして返します。
import React from 'react'
import Child from './Child';
export default function Parent() {
return (
<div>
<Child/>
</div>
)
}
そして関数と、その関数をトリガーするボタンを作成します。さらに useState フックを使用して、データを管理する state を作成します。
import React from 'react'
import Child from './Child';
import { Button } from 'semantic-ui-react';
import { useState } from 'react';
import './App.css';
export default function Parent() {
const [data, setData] = useState('');
const parentToChild = () => {
setData("This is data from Parent Component to the Child Component.");
}
return (
<div className="App">
<Child/>
<div>
<Button primary onClick={() => parentToChild()}>Click Parent</Button>
</div>
</div>
)
}
上記のコードでは、Click Parent ボタンがクリックされた時に parentToChild 関数を呼び出します。Click Parent ボタンがクリックされると、data 変数に "This is data from Parent Component to the Child Component" が格納されます。
では次に、その data という state を Child コンポーネントに受け渡します。これは props を用いて実現できます。
下記のように、Child コンポーネントを呼び出す際に data を props として受け渡します。
<Child parentToChild={data}/>
ここでは data というデータを Child コンポーネントに受け渡しています。
data
が受け渡したいデータで、parentToChild
が props の名前です。
次は、そのデータを Child コンポーネント側で受け取ります。これはとてもシンプルです。
これには 2 通りのケースがあります。
ケース 1: 関数コンポーネントを使用している場合は、引数で parentToChild を受け取ります。
import React from 'react'
export default function Child({parentToChild}) {
return (
<div>
{parentToChild}
</div>
)
}
ケース 2: クラスコンポーネントの場合は、this.props.parentToChild
を使用します。
import React, { Component } from 'react'
export default class Child extends Component {
render() {
return (
<div>
{this.props.parentToChild}
</div>
)
}
}
どちらのやり方でも同じ結果になります。

Click Parent
ボタンをクリックすると、データが画面に出力されます。
import React from 'react'
import Child from './Child';
import { Button } from 'semantic-ui-react';
import { useState } from 'react';
import './App.css';
export default function Parent() {
const [data, setData] = useState('');
const parentToChild = () => {
setData("This is data from Parent Component to the Child Component.");
}
return (
<div className="App">
<Child parentToChild={data}/>
<div className="child">
<Button primary onClick={() => parentToChild()}>Click Parent</Button>
</div>
</div>
)
}
Parent
コンポーネントの完成形のコードは上記の通りです。
子コンポーネントから親コンポーネントにデータを受け渡す方法
こちらは少し厄介です。
まず、Parent コンポーネント内に childToParent
という名前の関数と、data
という名前の空の state を作成します。
const [data, setData] = useState('');
const childToParent = () => {
}
次に、childToParent
関数を props として Child コンポーネントに受け渡します。
<Child childToParent={childToParent}/>
そして Child コンポーネント内で、この関数を props として受け取り、onClick イベントに割り当てます。
さらに、文字列または数値形式のデータを持つ state (data) を宣言します。
その data を parentToChild
関数に引数として渡します。
import React from 'react'
import { Button } from 'semantic-ui-react';
export default function Child({childToParent}) {
const data = "This is data from Child Component to the Parent Component."
return (
<div>
<Button primary onClick={() => childToParent(data)}>Click Child</Button>
</div>
)
}
次に、Parent コンポーネント側で、このデータを childToParent
関数内で引数として受け取ります。
そして useState フックを使用して data を設定します。
import './App.css';
import { useState } from 'react';
import Child from './Child';
function Parent() {
const [data, setData] = useState('');
const childToParent = (childdata) => {
setData(childdata);
}
return (
<div className="App">
<div>
<Child/>
</div>
</div>
);
}
export default Parent;
次に、return 文の中でその data 変数を表示します。
import './App.css';
import { useState } from 'react';
import Child from './Child';
function Parent() {
const [data, setData] = useState('');
const childToParent = (childdata) => {
setData(childdata);
}
return (
<div className="App">
{data}
<div>
<Child childToParent={childToParent}/>
</div>
</div>
);
}
export default Parent;
Click Child
ボタンがクリックされると、子コンポーネントの data が親コンポーネントの data を上書きします。

これで、子コンポーネントから親コンポーネントへ、そして親コンポーネントから子コンポーネントへデータを受け渡す方法が分かりました。
onClick や OnChange のようなイベントを受け渡す
childToParent
関数の中で alert メソッドを呼び出すようにして、その関数を props として Child コンポーネントに受け渡します。
import './App.css';
import Child from './Child';
function Parent() {
const childToParent = () => {
alert("This is an alert from the Child Component")
}
return (
<div className="App">
<div className="child">
<Child childToParent={childToParent}/>
</div>
</div>
);
}
export default Parent;
そして Child コンポーネントで childToParent
を props として受け取り、ボタンの onClick イベントに割り当てます。
import React from 'react'
import { Button } from 'semantic-ui-react';
export default function Child({childToParent}) {
return (
<div>
<Button primary onClick={() => childToParent()}>Click Child</Button>
</div>
)
}
Child コンポーネント内のボタンをクリックすると、Parent コンポーネント内の関数が呼び出され、次のようなアラートが表示されます。

以上です!
もっといろいろ実験したければ、GitHub にコードを公開していますのでご利用ください。
この記事は以上です。学習を楽しんでください。