Axiosと反応フックの統合


そばArek Nawo
Axios 最も人気のあるHTTP JavaScriptクライアントライブラリの一つです.まず第一に、それはあなたがブラウザで、または、ノードで走っているかどうかにかかわらず同じ方法でそれを使うことができるという意味です.HTTP APIは両方とも異なっています.その上に、Axiosは、現代とうまく統合された約束ベースですasync/await JavaScriptの構文.
自動JSON変換またはビルトイン要求キャンセルのような言及された特徴と他のもののおかげで、Axiosはあなたのフロントエンドとバックエンドのための完全な選択です.あなたの例を与えるために、この記事では、カスタム反応フックを作成することによってあなたの反応アプリでAxiosを統合する方法を参照してください.あなたはそれの周りの快適なラッパーを構築する方法と同様にAxiosを使用することを学びます.

反応フックの非同期


React Hooks ステートフル反応コンポーネントを構築する簡単で機能的な方法を提供します.彼らは簡単に構成可能であり、簡単に消化機能に別のAPIやビジネスロジックをラップするために使用することができます.
フックでの作業は、非同期コードを扱うときに少し複雑になります.におけるuseEffect() 戻り値が存在する場合、メソッドはクリーンアップコールバックであることを期待しています.ということで、useEffect() 以下のコールバック:
const useAsyncStuff = () => {
  const [data, setData] = useState(null);
  const [error, setError] = useState("");
  const [loaded, setLoaded] = useState(false);

  useEffect(() => {
    const loadAsyncStuff = async () => {
      try {
        const response = await fetch(/* ... */);
        const json = await response.json();

        setData(json);
      } catch (error) {
        setError(error);
      } finally {
        setLoaded(true);
      }
    };

    loadAsyncStuff();
  }, []);

  return { data, error, loaded };
};
すべてのasyncタスクは内側にあるloadAsyncStuff() 関数.この関数は、宣言の直後に呼び出され、その進捗状況に関する情報をloaded and error . すべてのasyncタスクが成功すると、結果のデータがdata ; それ以外の場合、エラーが捕捉され、error . いずれの場合もloadedtrue を返します.内部ロジックのラッピングuseEffect() それは一度だけ実行します.
このような反応フックは、Asyncコードを簡単に処理し、プロセスの現在の状態についてユーザに必要な情報をすべて提供します.このように、コンポーネントは正確に何が起こっているかを反映できます.

斧フックの作成


さて、上記のテクニックを適用して斧フックを作りましょう.まず、プロジェクトにインストールされていることを確認します.
npm install axios
サンプルから始めましょうuseAxiosPost() フック.
const useAxiosPost = (url, payload) => {
  const [data, setData] = useState(null);
  const [error, setError] = useState("");
  const [loaded, setLoaded] = useState(false);

  useEffect(() => {
    (async () => {
      try {
        const response = await axios.post(
          url,
          payload
        );

        setData(response.data);
      } catch (error) {
        setError(error.message);
      } finally {
        setLoaded(true);
      }
    })();
  }, []);

  return { data, error, loaded };
};

あなたの好みに応じて、また、よりコンパクトにすることができます“伝統的な”約束の構文を好む可能性があります.
const useAxiosPost = (url, payload) => {
  const [data, setData] = useState(null);
  const [error, setError] = useState("");
  const [loaded, setLoaded] = useState(false);

  useEffect(() => {
    axios
      .post(url, payload)
      .then((response) => setData(response.data))
      .catch((error) => setError(error.message))
      .finally(() => setLoaded(true));
  }, []);

  return { data, error, loaded };
};
フックは斧のものを使いますpost() 短縮メソッドPOST 指定したデータを指定したURLに要求します.それ以外に、JSONのパース応答データはdata , エラーメッセージはerror . フックは以下のように使用できます:
const App = () => {
  const { data, error, loaded } = useAxiosPost(
    "https://httpbin.org/post",
    {
      message: "Hello World",
    }
  );
  const stringifiedData = useMemo(() => {
    return JSON.stringify(data || {});
  }, [data]);

  if (loaded) {
    return error ? (
      <span>Error: {error}</span>
    ) : (
      <p>{stringifiedData}</p>
    );
  }
  return <span>Loading...</span>;
};
ご覧のように、フックはすべての必要なデータを提供します.

フックの改善


強力な基盤を使用すると、フックの機能を改善することができます.を変えましょうpost() メソッドrequest() , リクエストメソッドを含む完全なリクエスト構成を渡します.また、cancel ユーザがリクエストをキャンセルできる機能.
const useAxios = (url, method, payload) => {
  const [data, setData] = useState(null);
  const [error, setError] = useState("");
  const [loaded, setLoaded] = useState(false);
  const controllerRef = useRef(new AbortController());
  const cancel = () => {
    controllerRef.current.abort();
  };

  useEffect(() => {
    (async () => {
      try {
        const response = await axios.request({
          data: payload,
          signal: controllerRef.current.signal,
          method,
          url,
        });

        setData(response.data);
      } catch (error) {
        setError(error.message);
      } finally {
        setLoaded(true);
      }
    })();
  }, []);

  return { cancel, data, error, loaded };
};
From v0.22.0 onwards , アクシオスサポートAbortController , リクエストのキャンセルを容易にし、そのカスタムを廃止するCancelToken API.Axiosを使ってリクエストをキャンセルするには、まず新しいAbortController インスタンス.This controller 一つ以上のHTTP要求を中止することを許します.反応フックで使われるとき、それは包まれなければなりませんuseRef または同様に、すべての再レンダリングに新しいインスタンスを作成しない.
最も重要な特性AbortController is signal , のインスタンスを保持するAbortSignal そして、コントローラが意味する要求に提供されるべきです.
Axiosリクエスト設定で提供されたシグナルで、リクエストをキャンセルすることはabort() コントローラインスタンスのメソッド.

オープンソースセッション


Webアプリケーションの生産におけるデバッグは、挑戦的で、時間がかかるかもしれません.OpenReplay フルストーリー、ログオンとhotjarにオープンソースの代替手段です.それはあなたが監視し、すべてのユーザーが再生し、どのようにすべての問題のためにあなたのアプリの行動を示す再生することができます.それはあなたのユーザーの肩を見ながら、ブラウザの検査官を開いているようなものだ.OpenReplayは現在利用可能なオープンソースの代替手段です.

ハッピーデバッギング、現代のフロントエンドチームStart monitoring your web app for free .

反応文脈による統合の拡張


フックはすでにすべての種類の要求に最適ですが、あなたはまだそれを組み合わせてそれをさらに得ることができますReact Context .
Axiosは機能性を提供するcreate separate instances ライブラリの設定が異なる.指定されたインスタンスを通じて行われるリクエストをすべて提供するために、カスタムURLの設定、例えばベースURLまたはデフォルトヘッダーを使用できます.これは、大規模なアプリケーションでは、同じ起源に多くの要求を行うか、さまざまなAPIを使用して接続を再利用する接続です.
その上に、Axiosはdefine interceptor functions ベースとカスタムの両方のインスタンス.これらは前にデータを傍受することを許します、例えば、要求は送られます、あるいはthen() コールバックが呼び出されます.そのように、リクエストと応答インターセプターの両方があります.
AxiosインスタンスをReactionと統合するには、Reactive Contextを使用できます.それはすべての子要素にどこからでも利用可能にするでしょうuseAxios() フックはリクエストを処理するために使用します.インスタンスが利用できない場合、フックは常にaxios .
これを実装するには、新しいコンテキストプロバイダーコンポーネントを作成します.
const AxiosContext = createContext(null);
const AxiosInstanceProvider = ({
  config = {},
  requestInterceptors = [],
  responseInterceptors = [],
  children,
}) => {
  const instanceRef = useRef(axios.create(config));

  useEffect(() => {
    requestInterceptors.forEach((interceptor) => {
      instanceRef.current.interceptors.request.use(
        interceptor
      );
    });
    responseInterceptors.forEach((interceptor) => {
      instanceRef.current.interceptors.response.use(
        interceptor
      );
    });
  }, []);

  return (
    <AxiosContext.Provider value={instanceRef.current}>
      {children}
    </AxiosContext.Provider>
  );
};
インサイドAxiosInstanceProvider コンポーネントを設定し、instanceRef すべてのインターセプターはuseEffect() コールバックは、再レンダリングに不要な処理を防ぐために.これを行うとuseAxios() コンテキストを使用するフックを調整するには、使用可能なAxiosインスタンスを提供します.
const useAxios = (url, method, payload) => {
  const [data, setData] = useState(null);
  const [error, setError] = useState("");
  const [loaded, setLoaded] = useState(false);
  const contextInstance = useContext(AxiosContext);
  const instance = useMemo(() => {
    return contextInstance || axios;
  }, [contextInstance]);
  const controllerRef = useRef(new AbortController());
  const cancel = () => {
    controllerRef.current.abort();
  };

  useEffect(() => {
    (async () => {
      try {
        const response = await instance.request({
          signal: controllerRef.current.signal,
          data: payload,
          method,
          url,
        });

        setData(response.data);
      } catch (error) {
        setError(error.message);
      } finally {
        setLoaded(true);
      }
    })();
  }, []);

  return { cancel, data, error, loaded };
};
コンテキストはuseContext() フックにcontextInstance 変数.実際instance 結果useMemo() それが文脈で提供されないならば、計算とデフォルトのAxiosインスタンスを返すことができます.そのようなセットアップを使用するには、あなたのアプリケーションがAxiosInstanceProvider コンポーネント、少なくとも使用する場所よりも高いレベルuseAxios() フック.コンフィグや別のインターセプターをコンポーネント小道具として提供することができます.
const App = () => {
  return (
    <AxiosInstanceProvider
      config={{ baseURL: "https://httpbin.org/" }}
    >
      <Test>Test</Test>
    </AxiosInstanceProvider>
  );
};
それから、子コンポーネントの内部で、単に前のようなフックを使ってください.コンテキストの使用、送信、および処理はすべてバックグラウンドで行われます.
const Test = () => {
  const { data, error, loaded } = useAxios(
    "/post",
    "POST",
    {
      message: "Hello World",
    }
  );
  const stringifiedData = useMemo(() => {
    return JSON.stringify(data || {});
  }, [data]);

  if (loaded) {
    return error ? (
      <span>Error: {error}</span>
    ) : (
      <p>{stringifiedData}</p>
    );
  }
  return <span>Loading...</span>;
};

ボトムライン


あなたのフロントエンドとノード間で一貫したデータ取得経験をしたいなら、Axiosは優れたライブラリです.バックエンド.HTTPクライアントの場合は、多くの機能とショートカットでは、最高の最も楽しい方法で欲しいものを達成する必要があります.
Axiosとの反応を組み合わせて、非同期タスクの上に大きな抽象化をもたらすことができます.反応フックのおかげで、人間工学とそのようなセットアップの使いやすさは、単に顕著です.あなたが次のプロジェクトでそれらの2つを使いたいならば、あなたはちょうど方法を学びました.