Reactでデータを取得する3つの方法と長所短所


読める性を保証するために、本文は直訳ではなく意訳を採用する。
I/O動作(例えばデータ抽出)を実行する場合は、まずネットワーク要求を送信し、その後、応答を待って、その後、応答データをコンポーネントの状態に保存し、最後にレンダリングする。
Reactでライフサイクル方法、Hooks、Suspenseはデータを取得する方法です。次に、事例を使って、それらをどのように使って、各方法の長所と短所を説明します。
1.ライフサイクル方法でデータを要求する
アプリケーションEmployees.orgは2つのことをする。
1.プログラムに入ると20人の従業員を取得する。
2.フィルタ条件によって従業員を選別することができます。

これらの2つの需要を達成する前に、まずReactクラスのコンポーネントの2ライフサイクル方法を振り返ってみよう。componentDidMount():コンポーネントをマウントして実行するcomponentDidUpdate(prevProps)propsまたはstateが変更されたときに実行される。
コンポーネント<EmployeesPage>は、上記の2つのライフサイクル方法を用いて取得ロジックを実現する。

import EmployeesList from "./EmployeesList";
import { fetchEmployees } from "./fake-fetch";

class EmployeesPage extends Component {
 constructor(props) {
 super(props);
 this.state = { employees: [], isFetching: true };
 }

 componentDidMount() {
 this.fetch();
 }

 componentDidUpdate(prevProps) {
 if (prevProps.query !== this.props.query) {
  this.fetch();
 }
 }

 async fetch() {
 this.setState({ isFetching: true });
 const employees = await fetchEmployees(this.props.query);
 this.setState({ employees, isFetching: false });
 }

 render() {
 const { isFetching, employees } = this.state;
 if (isFetching) {
  return <div>       ...</div>;
 }
 return <EmployeesList employees={employees} />;
 }
}
codesadboxを開くと、<EmployeesPage>取得プロセスを見ることができる。<EmployeesPage>には、データを取得する非同期方法fetch()がある。取得要求が完了した後、setState方法を用いてemployeesを更新する。this.fetch()は、コンポーネントの初期レンダリング時に従業員データを取得するcomponentDidMount()ライフサイクル方法で実行される。
私たちのキーワードがフィルタリングされるとprops.queryが更新されます。props.queryが更新されるたびに、componentDidUpdate()this.fetch()を再実行する。
ライフサイクル法は比較的把握しやすいですが、クラスベースの方法にはサンプルコードがあり、再利用性が難しくなります。
長所
この方法は、componentDidMount()が第1レンダリング時にデータを取得し、componentDidUpdate()props更新時にデータを再取得することを容易に理解できる。
欠点
サンプルコード
クラスベースのコンポーネントは、React.Componentを継承し、構造関数でsuper(props)などを実行する必要がある。
thisthisのキーワードを使うのは面倒くさいです。
コードの重複componentDidMount()およびcomponentDidUpdate()のコードの多くは重複している。
重用はむずかしい
従業員が論理を得るのは難しいです。他のコンポーネントで再利用します。
2.Hooksでデータを取得する
Hooksはクラスに基づいてデータを取得する方式がより良い選択です。簡単な関数として、Hooksはクラスのコンポーネントのように継承されていないし、再利用も容易です。
簡単にuseEffect(callback[, deps]) Hookを思い出してください。このHookは、アップロード後にcallbackを実行し、依存項depsが変化したときに再レンダリングする。<EmployeesPage>を使用して、以下の例に示すように、従業員データを取得する。

import EmployeesList from "./EmployeesList";
import { fetchEmployees } from "./fake-fetch";

function EmployeesPage({ query }) {
 const [isFetching, setFetching] = useState(false);
 const [employees, setEmployees] = useState([]);

 useEffect(function fetch() {
 (async function() {
  setFetching(true);
  setEmployees(await fetchEmployees(query));
  setFetching(false);
 })();
 }, [query]);
 
 if (isFetching) {
 return <div>Fetching employees....</div>;
 }
 return <EmployeesList employees={employees} />;
}
codesadboxを開くと、useEffect()がデータをどうやって取得するかを確認することができる。
Hooksを使用するuseEffect()は、クラス構成要素を使用するよりもはるかに簡単であることが見られます。<EmployeesPage>関数構成要素の<EmployeesPage>において、初期レンダリングの後にuseEffect(fetch, [query])コールが実行される。また、依存項fetchが更新されると、query方法が再実行される。

しかし、最適化の余地はまだあります。Hooksはfetchコンポーネントから従業員を抽出して論理を得ることができます。

import React, { useState } from 'react';

import EmployeesList from "./EmployeesList";
import { fetchEmployees } from "./fake-fetch";

function useEmployeesFetch(query) { //      
 const [isFetching, setFetching] = useState(false);
 const [employees, setEmployees] = useState([]);

 useEffect(function fetch {
 (async function() {
  setFetching(true);
  setEmployees(await fetchEmployees(query));
  setFetching(false);
 })();
 }, [query]);

 return [isFetching, employees];
}

function EmployeesPage({ query }) {
 const [employees, isFetching] = useEmployeesFetch(query); //      
 
 if (isFetching) {
 return <div>Fetching employees....</div>;
 }
 return <EmployeesList employees={employees} />;
}
必要な値は<EmployeesPage>から言及される。コンポーネントuseEmployeesFetch()は、対応する取得ロジックがなく、レンダリングインターフェースの動作のみを担当する。
より良いのは、従業員を取得する必要がある他の任意のコンポーネントで<EmployeesPage>を再利用することができる。
長所
分かりやすくて簡単です
Hooksにはサンプルコードがありません。普通の関数です。
再利用可能性
Hooksで実現される取得データロジックは再利用しやすいです。
欠点は前置きの知識が必要です。
Hooksは直感に反していますので、使う前には理解しておかなければなりません。Hooksはクローズドに依存していますので、よく知っておいてください。
必要性
Hooksを使用しても、コマンド方式でデータ取得を実行しなければなりません。
3.suspenseでデータを取得するuseEmployeesFetch()は、React中のデータを非同期的に取得するための声明的な方法を提供する。
注意:2019年11月現在、Suspenseは試験段階にあります。Suspense包装は非同期動作を実行するコンポーネント:

<Suspense fallback={<span>Fetch in progress...</span>}>
 <FetchSomething />
</Suspense>
データ取得時、<Suspense>Suspenseの内容を表示し、データ取得後、fallbackはデータレンダリングSuspenseに使用する。<FetchSomething />はどうやって使いますか?

import React, { Suspense } from "react";
import EmployeesList from "./EmployeesList";

function EmployeesPage({ resource }) {
 return (
 <Suspense fallback={<h1>Fetching employees....</h1>}>
  <EmployeesFetch resource={resource} />
 </Suspense>
 );
}

function EmployeesFetch({ resource }) {
 const employees = resource.employees.read();
 return <EmployeesList employees={employees} />;
}
codesadboxを開くと、Suspenseがデータをどうやって取得するかを確認することができる。Suspenseは、<EmployeesPage>処理コンポーネントを使用して、取得したデータをSuspenseコンポーネントに渡す。<EmployeesFetch><EmployeesFetch>は、resource.employeesと背後で通信する特殊な包装promiseである。このように、Suspenseは、「起」Suspenseのレンダリングにどれぐらいの時間がかかるかを知り、リソースの準備が整い次第、レンダリング作業を開始する。
最大の利点は、非同期動作を宣言的かつ同期的に処理することである。コンポーネントは複雑なデータ取得ロジックではなく、ステートメント方式でリソースを使用してコンテンツをレンダリングする。コンポーネントの内部にライフサイクルがなく、Hooksがなく、<EmployeesFetch>がありません。インターフェースのみを表示します。
長所
宣言式Suspenseは、ステートメントとしてReactで非同期動作を実行する。
シンプル
これらのコンポーネントは複雑なデータ取得ロジックを持っていません。
松カップリングと獲得実現async/awaitのコンポーネントを使用すると、データの取得方法が分かりません。RESTまたはGraphQLを使用します。Suspenseは、取得の詳細がコンポーネントにリークされることを保護する境界を設定する。
標準状態
複数の取得動作が要求された場合、Suspenseは最新の取得要求を使用する。
https://dmitripavlutin.com/react-fetch-lifecycle-methods-hooks-suspense/
4.まとめ
長い間、ライフサイクルの方法はずっとデータ方式の唯一の解決策です。しかし、それらを使ってデータを取得すると、多くのサンプルコード、繰り返し、再利用可能性の問題があります。
Hooksを使ってデータを取得するのはより良い選択です。より少ないサンプルコードです。Suspenseの利点は、ステートメント取得である。私たちのコンポーネントは獲得されません。実現の細部がめちゃくちゃになります。Suspenseは、React自体の宣言的な本質により近い。
https://dmitripavlutin.com/react-fetch-lifecycle-methods-hooks-suspense/
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。