質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Redux

Reduxは、JavaScriptアプリケーションの状態を管理するためのオープンソースライブラリです。ReactやAngularで一般的にユーザーインターフェイスの構築に利用されます。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

0回答

1056閲覧

【React,Redux,TypeScript】 dropzone にてファイル取得後 reducer にてエラーが出てしまう

misumi

総合スコア0

Redux

Reduxは、JavaScriptアプリケーションの状態を管理するためのオープンソースライブラリです。ReactやAngularで一般的にユーザーインターフェイスの構築に利用されます。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2021/01/20 08:19

前提・実現したいこと

react-dropzone を用いて
取得した画像やPDF等のファイルデータを扱おうとしました。
ですが、dispatchを通した時にエラーとなってしまい
先に進めず、困っています。

環境
+-- react@17.0.1
+-- react-dom@17.0.1
+-- react-dropzone@11.2.4
+-- react-redux@7.2.2
+-- react-scripts@4.0.1
`-- typescript@3.8.3

npx create-react-app . --template redux-typescript

npm install --save react-dropzone

console に出されるエラーメッセージ

調べてみても、シリアル化できないというような理解しかできず
対応できなくなりました。

A non-serializable value was detected in an action, in the path: `payload.document`. Value: File {path: "gel-capsules-5834023_1280.jpg", name: "gel-capsules-5834023_1280.jpg", lastModified: 1609893376819, lastModifiedDate: Wed Jan 06 2021 09:36:16 GMT+0900 (日本標準時), webkitRelativePath: "", …}lastModified: 1609893376819lastModifiedDate: Wed Jan 06 2021 09:36:16 GMT+0900 (日本標準時) {}name: "gel-capsules-5834023_1280.jpg"path: "gel-capsules-5834023_1280.jpg"size: 148443type: "image/jpeg"webkitRelativePath: ""__proto__: File Take a look at the logic that dispatched this action: {type: "drop/incrementFile", payload: {…}} (See https://redux.js.org/faq/actions#why-should-type-be-a-string-or-at-least-serializable-why-should-my-action-types-be-constants) (To allow non-serializable values see: https://redux-toolkit.js.org/usage/usage-guide#working-with-non-serializable-data)

ブラウザ に出されるエラーメッセージ

Unhandled Rejection (Error): Invariant failed: A state mutation was detected between dispatches, in the path 'drop.files.0.document.lastModifiedDate'. This may cause incorrect behavior. (https://redux.js.org/troubleshooting#never-mutate-reducer-arguments)

該当のソースコード

Drop.tsx

onDrop内、コメントの部分以降のdispatchで引っ掛かります

react

1import React, { useCallback } from 'react'; 2import { useSelector, useDispatch } from 'react-redux'; 3import { incrementFile, selectMyFile } from './dropSlice'; 4import { makeStyles, createStyles, Theme } from '@material-ui/core/styles'; 5 6import { 7 Typography, 8 Paper 9} from '@material-ui/core/'; 10 11import { useDropzone } from 'react-dropzone' 12import { MY_FILE } from '../Types'; 13 14// スタイル 15const useStyles = makeStyles((theme: Theme) => 16 createStyles({ 17 root: { 18 display: 'flex', 19 }, 20 paper: { 21 padding: theme.spacing(2), 22 textAlign: 'center', 23 '& > *': { 24 margin: theme.spacing(3), 25 }, 26 }, 27 dropzone: { 28 width: "100%", 29 height: 200, 30 boxSizing: "border-box", 31 borderWidth: 2, 32 borderColor: "#666666", 33 borderStyle: "dashed", 34 borderRadius: 5, 35 verticalAlign: "top", 36 marginRight: "2%", 37 }, 38 }), 39); 40 41// Dropzone 42const acceptFile = ['image/*', '.pdf']; 43const maxFileSize = 10485760; 44 45export function Drop() { 46 const files = useSelector(selectMyFile); 47 const dispatch = useDispatch(); 48 const classes = useStyles(useStyles); 49 50 const onDrop = useCallback((acceptedFiles: File[]) => { 51 52 acceptedFiles.forEach((file) => { 53 console.log(file); 54 55 const setFile: MY_FILE = { 56 title: file.name, 57 document: file,/// null でエラーなし 58 } 59   /// ここから先にてエラー 60 dispatch(incrementFile(setFile)); 61 }) 62 63 }, []) 64 // Dropzone 65 const { getRootProps, getInputProps, isDragActive } 66 = useDropzone({ onDrop, accept: acceptFile, minSize: 0, maxSize: maxFileSize }) 67 68 const filesList = files.map(file => ( 69 <li key={file.title}> 70 {file.title} 71 </li> 72 )); 73 return ( 74 <div> 75 <Paper variant="outlined" elevation={3} className={classes.paper}> 76 <Typography variant="h4">Drop test</Typography> 77 <div> 78 <Paper className={classes.dropzone} {...getRootProps()}> 79 <input {...getInputProps()} /> 80 { 81 isDragActive ? 82 <p>Drop the files here ...</p> : 83 <p>Drag 'n' drop some files here, or click to select files</p> 84 } 85 </Paper> 86 </div> 87 </Paper> 88 <aside> 89 <h4>Files</h4> 90 <ul>{filesList}</ul> 91 </aside> 92 </div> 93 ); 94} 95 96export default Drop; 97

dropSlice.ts

react

1import { createSlice, PayloadAction } from '@reduxjs/toolkit'; 2import { RootState } from '../../app/store'; 3import { MY_FILE, DROP_STATE } from '../Types' 4 5const initialState: DROP_STATE = { 6 files: [{ 7 title: "", 8 document: null, 9 } 10 ], 11}; 12 13export const dropSlice = createSlice({ 14 name: 'drop', 15 initialState, 16 reducers: { 17 incrementFile(state, action: PayloadAction<MY_FILE>) { 18 state.files[0].title === '' ? state.files[0] = action.payload : 19 state.files = [...state.files, action.payload] 20 } 21 }, 22}); 23 24export const { incrementFile } = dropSlice.actions; 25 26export const selectMyFile = (state: RootState) => state.drop.files; 27 28export default dropSlice.reducer; 29

Types.ts

react

1 2export interface MY_FILE { 3 title: string; 4 document: File | null; 5} 6 7export interface DROP_STATE { 8 files: MY_FILE[]; 9}

App.tsx

react

1import React from 'react'; 2import { Drop } from './features/drop/Drop'; 3import './App.css'; 4 5function App() { 6 return ( 7 <div className="App"> 8 <Drop /> 9 </div> 10 ); 11} 12 13export default App; 14

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問