为何无法在Redux Toolkit状态中设置File类型变量?
问题分析与解决方法
核心问题:错误的reducer定义
你的slice里定义了getAssignorsList和getAssignorFileSignToUpdate这两个reducer,这是完全错误的用法。Redux的reducer是用来修改状态的,不是用来读取状态的。当你dispatch这两个action时,会直接替换整个slice的状态:
- 调用
getAssignorFileSignToUpdate后,整个assignorsslice的状态会被替换成state.assignorFileSignToUpdate的值(也就是你设置的File对象) - 之后再通过
useSelector(state => state.assignors.assignorFileSignToUpdate)获取时,因为整个slice状态已经变成了File对象,不再有assignorFileSignToUpdate这个属性,所以会拿到undefined或显示为空白对象
解决步骤
1. 删除错误的getter reducer
把slice里的getAssignorsList和getAssignorFileSignToUpdate这两个reducer删掉,同时在导出actions时也去掉它们:
修改后的slice代码:
import { createSlice } from "@reduxjs/toolkit" export const assignorsSlice = createSlice({ name: "assignors", initialState: { list: [], assignorFileSignToUpdate: null, }, reducers: { setAssignorsList: (state, action) => { state.list = action.payload }, addAssignor: (state, action) => { state.list.push(action.payload) }, toggleAssignor: (state, action) => { const rut = action.payload const assignor = state.list.find((assignor) => { return assignor.rut === rut }) assignor.active = !assignor.active }, setAssignorFileSignToUpdate: (state, action) => { state.assignorFileSignToUpdate = action.payload console.log( "🚀 ~ file: assignors.js ~ line 28 ~ action.payload", action.payload ) console.log( "🚀 ~ file: assignors.js ~ line 29 ~ state.assignorFileSignToUpdate", state.assignorFileSignToUpdate ) }, }, }) // export actions export const { setAssignorsList, addAssignor, toggleAssignor, setAssignorFileSignToUpdate, } = assignorsSlice.actions export default assignorsSlice.reducer
2. 验证File对象是否正确存储
在组件中使用useSelector获取状态时,验证File对象的有效性:
import { useSelector } from 'react-redux'; const YourComponent = () => { const file = useSelector(state => state.assignors.assignorFileSignToUpdate); console.log('File是否存在:', !!file); if (file) { console.log('是否为File实例:', file instanceof File); console.log('文件名:', file.name); console.log('文件大小:', file.size); } // ...其他代码 }
3. 关于Redux DevTools显示空白的说明
File是浏览器原生对象,它的很多属性是不可枚举的,Redux DevTools在序列化状态时只能显示可枚举属性,所以会显示为空白对象,但这并不影响File对象的实际功能。如果你需要在DevTools里查看File的信息,可以手动提取关键属性存储,比如:
// 在设置状态时,存储File的关键属性+原File对象 setAssignorFileSignToUpdate: (state, action) => { const file = action.payload; state.assignorFileSignToUpdate = { file: file, name: file.name, size: file.size, type: file.type, lastModified: file.lastModified }; }
之后使用时直接取file.file即可,DevTools也能看到这些属性。
内容的提问来源于stack exchange,提问作者Nikko
相关产品推荐
相关产品推荐

