LoginSignup
0
0

Redux Toolkit でファイルのダウンロードで発生する A non-serializable value was detected への対処

Posted at
A non-serializable value was detected

Redux Toolkit でAPIサーバーで生成したファイルを取得しようとしたら上記のエラーが発生してハマったので対処方法を記しておきます。

Redux Toolkit は基本的にAPIなどから取得したデータは全てシリアライズして Store に保持する設計になっています。
ファイルのような巨大なバイナリデータはそもそもキャッシュの対象外なので Store に値を渡さないような細工が必要になります。

サンプルコード

RTK Queryqueryfn を使って Store に値を渡す前にファイルダウンロードを実行し、 Store にはダミーデータを渡しています。

const downloadFile = (blob, fileName) => {
  const elm = document.createElement('a');
  const url = window.URL || window.webkitURL;
  const fileUrl = url.createObjectURL(blob);
  elm.href = fileUrl;
  elm.target = '_blank';
  elm.download = fileName;
  elm.click();
};

export const downloadFileApi = apiBase.injectEndpoints({
  endpoints: (builder) => ({
    downloadFile: builder.mutation({
      queryFn: async (params, api, extraOptions, baseQuery) => {
        const result = await baseQuery({
          url: '/something/file',
          method: 'POST',
          body: params.apiParams,
          responseHandler: ((response) => response.blob())
        })

        downloadFile(result.data, params.fileName);

        return { data: null };
      }
    }),
  }),
});

export const {
  useDownloadFileMutation
} = downloadFileApi;

上記のAPIクライアントの呼び出し側の実装は以下のようになります。

const [downloadPdf] = useDownloadPdfMutation();

const downloadAction = () => {
  const params = {
    apiParams: {  }, // 略
    fileName: 'hoge'
  };

  downloadPdf(params);
};

参考サイト

以下のリンク先のIssueのコードを参考にしています、感謝!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0