Reactで呼び出し元の部品にデータを渡すには?
Reactで呼び出し元の部品にデータを渡すには?
2022年6月19日
React で呼び出し元の部品にデータを渡すには?
Veu の場合、呼び出し元(親)の部品に、呼び出される(子)の部品からデータを渡す機能があります。React の場合にも似たような機能を実装できますが、考え方が少し違っています。この記事では、React で「子」から「親」にデータを渡す例を紹介します。
Vue の場合は?
Vue の場合は、公式チュートリアル(英語版)のステップ13で紹介されているように、「emit」を使うと、「子」の部品から「親」の部品にデータを送る事ができます。
<script>
export default {
emits: ["response"],
created() {
this.$emit("response", "hello from child");
},
};
</script>
この場合、「emits」で定義している、「response」という名前で、「this.$emit('response', 'XXXX')」を使うと、データを「親」の部品に送る事ができます。
この例では、「hello from child」というデータを「親」に送っています。
「親」の部品では、最初は「No child msg yet」というデータをセットしておいて、データが送られてきた場合には、送られてきたデータに更新するという処理を行なっています。
Vue の場合は、公式チュートリアル(英語版)のステップ13で紹介されているように、「emit」を使うと、「子」の部品から「親」の部品にデータを送る事ができます。
<script>
export default {
emits: ["response"],
created() {
this.$emit("response", "hello from child");
},
};
</script>
この場合、「emits」で定義している、「response」という名前で、「this.$emit('response', 'XXXX')」を使うと、データを「親」の部品に送る事ができます。
この例では、「hello from child」というデータを「親」に送っています。
「親」の部品では、最初は「No child msg yet」というデータをセットしておいて、データが送られてきた場合には、送られてきたデータに更新するという処理を行なっています。
React ではどうするか?
実は、React の場合、基本的な考えとして、「子」の部品から「親」の部品にデータを送るような Vue の機能はサポートされていません。基本的に、データのやり取りは「親」の部品から「子」の部品への一方通行になっています。
そう考えると、Vue の方が機能が多く、優れているように思いがちですが、同じ様な機能は React でも実現可能です。この場合、「親」の部品で設定した、「No child msg yet」という表示データを、「子」の部品で、「hello from child」に更新するという処理です。
React で処理する場合には、「子」の部品から「親」の部品にデータを送るのではなく、「子」の部品で、「親」のステート管理しているデータの更新を行うという方法で同じ機能を実現しています。
実際に実装例を先に紹介します。
import React, { SetStateAction, useState } from "react";
import Step13Child from "./step13Child";
import "./styles/step13.css";
export default function Step13(): JSX.Element {
const [childMsg, setChildMsg]: [
string,
React.Dispatch<SetStateAction<string>>
] = useState("No child msg yet");
return (
<React.Fragment>
<div>
<Step13Child report={setChildMsg} />
<p>{childMsg}</p>
</div>
</React.Fragment>
);
}
ステート管理している変数「childMsg」を更新する関数「setChildMsg()」を「子」の部品に渡して、「子」の部品側でデータの更新をできるようにするという仕組みです。
「子」の部品側では、この受け取った関数を使って「親」の表示データを更新します。
import React, { SetStateAction, useEffect } from "react";
interface IProps {
report: React.Dispatch<SetStateAction<string>>;
}
export default function Step13Child(props: IProps): JSX.Element {
useEffect((): void => {
props.report("hello from child");
});
return (
<React.Fragment>
<div>
<h2>Child component</h2>
</div>
</React.Fragment>
);
}
この例では、Vue の公式チュートリアル(英語版)のステップ13とほぼ同じように、「子」の部品側のデータを使って、「親」の表示を更新しています。見た目の機能は Vue のステップ13とこの上に上げた処理は同じように動作します。
実は、React の場合、基本的な考えとして、「子」の部品から「親」の部品にデータを送るような Vue の機能はサポートされていません。基本的に、データのやり取りは「親」の部品から「子」の部品への一方通行になっています。
そう考えると、Vue の方が機能が多く、優れているように思いがちですが、同じ様な機能は React でも実現可能です。この場合、「親」の部品で設定した、「No child msg yet」という表示データを、「子」の部品で、「hello from child」に更新するという処理です。
React で処理する場合には、「子」の部品から「親」の部品にデータを送るのではなく、「子」の部品で、「親」のステート管理しているデータの更新を行うという方法で同じ機能を実現しています。
実際に実装例を先に紹介します。
import React, { SetStateAction, useState } from "react";
import Step13Child from "./step13Child";
import "./styles/step13.css";
export default function Step13(): JSX.Element {
const [childMsg, setChildMsg]: [
string,
React.Dispatch<SetStateAction<string>>
] = useState("No child msg yet");
return (
<React.Fragment>
<div>
<Step13Child report={setChildMsg} />
<p>{childMsg}</p>
</div>
</React.Fragment>
);
}
ステート管理している変数「childMsg」を更新する関数「setChildMsg()」を「子」の部品に渡して、「子」の部品側でデータの更新をできるようにするという仕組みです。
「子」の部品側では、この受け取った関数を使って「親」の表示データを更新します。
import React, { SetStateAction, useEffect } from "react";
interface IProps {
report: React.Dispatch<SetStateAction<string>>;
}
export default function Step13Child(props: IProps): JSX.Element {
useEffect((): void => {
props.report("hello from child");
});
return (
<React.Fragment>
<div>
<h2>Child component</h2>
</div>
</React.Fragment>
);
}
この例では、Vue の公式チュートリアル(英語版)のステップ13とほぼ同じように、「子」の部品側のデータを使って、「親」の表示を更新しています。見た目の機能は Vue のステップ13とこの上に上げた処理は同じように動作します。
考え方の違い
Vue の場合では、「子」の部品から「親」の部品にデータを送って、「親」の部品側で、表示に利用するデータの更新を行うという方法で処理しています。今回の、React の例では、「親」の部品の表示に利用するデータを更新する関数を「子」の部品に渡して、「子」の部品側で、「親」の表示データを更新しています。
結果的に、「子」のデータを使って、「親」の表示データを更新しているので、見かけ上は同じになっています。つまり、React のデータの受け渡しは一方通行ですが、データを処理する関数を渡すことで「子」からデータを「親」に送らずに同じ機能を実現しているという事になります。
要は、Vue と React の基本的な設計思想の違いです。
プログラミングの実装では、同じ様な機能を色々な違った方法を使って実現できます。React と Vue の実装方法の違いもその一つという事になります。
Vue の場合では、「子」の部品から「親」の部品にデータを送って、「親」の部品側で、表示に利用するデータの更新を行うという方法で処理しています。今回の、React の例では、「親」の部品の表示に利用するデータを更新する関数を「子」の部品に渡して、「子」の部品側で、「親」の表示データを更新しています。
結果的に、「子」のデータを使って、「親」の表示データを更新しているので、見かけ上は同じになっています。つまり、React のデータの受け渡しは一方通行ですが、データを処理する関数を渡すことで「子」からデータを「親」に送らずに同じ機能を実現しているという事になります。
要は、Vue と React の基本的な設計思想の違いです。
プログラミングの実装では、同じ様な機能を色々な違った方法を使って実現できます。React と Vue の実装方法の違いもその一つという事になります。
React のデータのやり取りは一方通行
React の場合には、データ(関数なども含めて)のやり取りは、基本的に「親」から「子」の一方通行と考えてください。データを「子」から「親」に渡せない代わりに、データを処理する「関数」を「親」から「子」に渡すことで、データを「親」に渡せなくても、同じ様な機能が実現できるように設計します。
通常の実装ではこの方法で十分です。さらに複雑なデータのやり取りが必要な場合には、データを一括管理する方法を利用します。Redux などの利用がその例です。一見、「子」から「親」にデータが渡せないと不便な感じがしますが、実は大きな違いではありません。
React の場合には、データ(関数なども含めて)のやり取りは、基本的に「親」から「子」の一方通行と考えてください。データを「子」から「親」に渡せない代わりに、データを処理する「関数」を「親」から「子」に渡すことで、データを「親」に渡せなくても、同じ様な機能が実現できるように設計します。
通常の実装ではこの方法で十分です。さらに複雑なデータのやり取りが必要な場合には、データを一括管理する方法を利用します。Redux などの利用がその例です。一見、「子」から「親」にデータが渡せないと不便な感じがしますが、実は大きな違いではありません。
まとめ
今回は、「子」のデータを「親」の部品で利用する例を紹介しました。 Vue の場合は、「子」から「親」にデータを渡すという形で紹介されていますが、実際には、「子」のデータを「親」の表示に反映させる機能という方が一般的な表現です。
そう考えた場合、直接データを「子」から「親」に渡せなくても、同じ様な機能が実現できます。
React と Vue では設計思想が少し違っているので、機能を比べると React が劣っている様に見える場合がありますが、機能的には大きな違いはありません。
それぞれの、フレームワークでの機能の実装の方法をよく理解しておく事が重要になります。
今回は、「子」のデータを「親」の部品で利用する例を紹介しました。 Vue の場合は、「子」から「親」にデータを渡すという形で紹介されていますが、実際には、「子」のデータを「親」の表示に反映させる機能という方が一般的な表現です。
そう考えた場合、直接データを「子」から「親」に渡せなくても、同じ様な機能が実現できます。
React と Vue では設計思想が少し違っているので、機能を比べると React が劣っている様に見える場合がありますが、機能的には大きな違いはありません。
それぞれの、フレームワークでの機能の実装の方法をよく理解しておく事が重要になります。
コメント
コメントを投稿