nomurabbitのブログ

nomurabbitのブログはITを中心にした技術ブログです。

nomurabbitのブログ

【Typescript】axiosのREADME読んでみた Part8【React】

この記事はReactaxiosを使うために、axiosのREADMEを読んで得た情報をまとめたものです。React×Typescriptのサンプルコードも載せています。

こんにちは!nomurabbitです。今回はaxiosに関する記事です。

Part8の今回はリクエストのキャンセルについてです。Typescriptの解説やサンプルコードを交えて一緒に勉強していきましょう

Cancellation

You can cancel a request using a cancel token.
The axios cancel token API is based on the withdrawn cancelable promises proposal.
You can create a cancel token using the CancelToken.source factory as shown below:

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function (thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // handle error
  }
});

axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token
})

// cancel the request (the message parameter is optional)
source.cancel('Operation canceled by the user.');

You can also create a cancel token by passing an executor function to the CancelToken constructor:

const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // An executor function receives a cancel function as a parameter
    cancel = c;
  })
});

// cancel the request
cancel();

キャンセルトークンを使ってHTTPリクエストをキャンセルできるんですね。

Typescriptでサンプルコードを書いてみましょう!

サンプルコード1 nomurabbit ver.

  const CancelToken = axios.CancelToken;
  const source = CancelToken.source();

  const [httpRequestMessage, setHttpRequestMessage] = useState<IhttpRequestPostMessage>();

  useEffect(() => {
    if(httpRequestMessage !== undefined){
      getHttpPostResponsePost();
    }
  },[httpRequestMessage]);
  
  return (
    <ResponsiveDrawer>
      <div>
        <p>axios sample page.</p>
        <p>
        <button onClick={() => setHttpRequestMessage({strikeout: "100", wakls:"1"})}>
          Click me
        </button>
        </p><p>
        <button onClick={() => {source.cancel('Operation canceled by the user.');}}>
          Cancel
        </button>
        </p>
      </div>
    </ResponsiveDrawer>
  );

サンプルコード2 nomurabbit ver.

  const CancelToken = axios.CancelToken;
  let cancel : Canceler;

  const getHttpPostResponsePost = () => {
    axios.post(apiUrlPost,httpRequestMessage,{
      headers: {'Content-Type': 'text/plain'},
      cancelToken: new CancelToken((c) =>  {
        cancel = c;
      })
    }).then(function (response) {
      console.log(response);
    }).catch(function (thrown) {
      if (axios.isCancel(thrown)) {
        console.log('Post Request canceled', thrown.message);
      } else {
        console.log(thrown);
      }
    });
  }

  const [httpRequestMessage, setHttpRequestMessage] = useState<IhttpRequestPostMessage>();

  useEffect(() => {
    if(httpRequestMessage !== undefined){
      getHttpPostResponsePost();
    }
  },[httpRequestMessage]);
  
  return (
    <ResponsiveDrawer>
      <div>
        <p>axios sample page.</p>
        <p>
        <button onClick={() => setHttpRequestMessage({strikeout: "100", wakls:"1"})}>
          Click me
        </button>
        </p><p>
        <button onClick={() => {cancel('Operation canceled by the user.');}}>
          Cancel
        </button>
        </p>
      </div>
    </ResponsiveDrawer>
  );

いずれも実行結果はこのようになります。

実行結果
f:id:nomurabbit:20211231063821p:plain

Click me > Cancelと順に押すと、

f:id:nomurabbit:20211231063844p:plain

リクエストがキャンセルされます。

Axios supports AbortController to abort requests in fetch API way:

AbortController を使ったキャンセルの例です。

const controller = new AbortController();

axios.get('/foo/bar', {
   signal: controller.signal
}).then(function(response) {
   //...
});
// cancel the request
controller.abort()

Typescriptだとこんな感じです。

サンプルコード3 nomurabbit ver.

  const controller = new AbortController();

  const getHttpPostResponsePost = () => {
    axios.post(apiUrlPost,httpRequestMessage,{
      headers: {'Content-Type': 'text/plain'},
      signal:controller.signal
    }).then(function (response) {
      console.log(response);
    }).catch(function (thrown) {
      if (axios.isCancel(thrown)) {
        console.log('Post Request canceled', thrown.message);
      } else {
        console.log(thrown);
      }
    });
  }

  const [httpRequestMessage, setHttpRequestMessage] = useState<IhttpRequestPostMessage>();

  useEffect(() => {
    if(httpRequestMessage !== undefined){
      getHttpPostResponsePost();
    }
  },[httpRequestMessage]);
  
  return (
    <ResponsiveDrawer>
      <div>
        <p>axios sample page.</p>
        <p>
        <button onClick={() => setHttpRequestMessage({strikeout: "100", wakls:"1"})}>
          Click me
        </button>
        </p><p>
        <button onClick={() => {controller.abort();}}>
          Cancel
        </button>
        </p>
      </div>
    </ResponsiveDrawer>
  );

こちらも実行結果は同様です。

ちなみに…。

Note: you can cancel several requests with the same cancel token/abort controller. If a cancellation token is already cancelled at the moment of starting an Axios request, then the request is cancelled immediately, without any attempts to make real request.

キャンセルトークンで処理がキャンセルされると、同じキャンセルトークに紐づいた処理は全てキャンセルされるということです。

というわけで今回はリクエストのキャンセルについて勉強してきましたが、axiosのREADME読んでみた Part8いかがでしたでしょうか?

次回もぜひご覧ください。では!

参考

axios
github.com