背景
Reactでシステムの検索条件の日付部分の実装にMaterial-UIのDate Picker
を使っていて、
その検索条件をReduxのstoreへ保存(dispatch送信)する際にブラウザのコンソールにエラーが出た。
ただし動作的には問題なさそう。
エラー内容
index.js:1 A non-serializable value was detected in an action, in the path: `payload.xx保存値の名称xx`. Value: Tue Aug 02 2022 22:24:42 GMT+0900 (日本標準時)
Take a look at the logic that dispatched this action: {type: 'xxxアクション名xxx', 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)
直訳すると、
「index.js:1 アクションのパス: `payload.xx保存値の名称xx` でシリアル化できない値が検出されました。値: Tue Aug 02 2022 22:24:42 GMT+0900 (日本標準時)
このアクションをディスパッチしたロジックを見てみましょう: {type: 'xxxアクション名xxx', payload: {…}}
(https://redux.js.org/faq/actions#why-should-type-be-a-string-or-at-least-serializable-why-should-my-action-types-be-constants を参照)
(シリアル化できない値を許可するには、https://redux-toolkit.js.org/usage/usage-guide#working-with-non-serializable-data を参照してください)」
とのこと。
エラーのリンクを参照すると、storeに入れる値はシリアライズ可能でなければならない、とある。
以下Redux Toolkitのサイトをみても、「シリアル化できない値を state または actions に入れるべきではない」と書いてある
https://redux-toolkit.js.org/usage/usage-guide#working-with-non-serializable-data
そもそも「シリアライズ」って何?となったので調べてみた。
シリアライズは「直列化」を意味する単語でオブジェクトが持つデータを、
コンピューターが読み書きできるようにバイナリデータへ変換する役割を持つ。
つまり今格納しようとしているのは変換できないデータってことと解釈。
そのため今回DATE型であることが原因のよう。
対応方法について検討
DATE型を止めればよさそうだが「Material-UIのDate Picker」を使うにあたり、
DATE型でなければならない。
悩んだ結果以下2つのパターンを検討。
対応方法.1
エラーが出ることを無視する方法
以下Redux Toolkitのサイトを参考に実装方法が書いてある
「ignoreActions」を使って無効にしたいアクションを指定すればよい。
”Take a look at the reducer(s) handling this action type: XXXX
.”
のXXXX
の部分を上記のignoredActionsに指定すればOK。
configureStore({
//...
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
// Ignore these action types
ignoredActions: ['your/action/type'],
// Ignore these field paths in all actions
ignoredActionPaths: ['meta.arg', 'payload.timestamp'],
// Ignore these paths in the state
ignoredPaths: ['items.dates'],
},
}),
})
対応方法.2
- storeへ値を保存する前に文字列化する
今回はこちらを採用した。
なんとなくだが、対応方法1.
のエラーを無効にするのは気が引けたため。
どういう場合に無効にするかはもう少し調べる必要がありそう。 - 保存時
変数名.toString() でstring型に変換して保存
- 使用時
new Date(変数名)
でDATE型に戻して使う
まとめ
このエラーに関する記事があまりなかったのでメモがてら書いてみました。
気づきがあれば追記・修正していきます。