我目前正在使用Material Ui dropzone上传多个文件。只是想知道在Redux商店中添加/更新文件的最佳方法是什么。我目前正在执行一个调度操作,当“onChange”触发器返回dropzone上的所有文件时,并通过存储具有files对象的整个files数组来更新Redux状态。请告诉我是否有最好的方法来处理这件事。
bbuxkriu1#
Redux的关键规则之一是不可序列化的值不应该进入存储。因此,如果可能的话,文件对象不应该保留在Redux存储中。
aemubtdh2#
我遇到了类似的问题,最后使用了这个:
URL.createObjectURL(file)
字符串它返回一个类似blob:http://example.com/f331074d-a7f3-4972-9c37-96b490a4dd96的url,它只是一个字符串,可以在img标签的src属性中使用。不确定Material Ui dropzone返回什么,但这适用于<input type="file" />返回的File对象
blob:http://example.com/f331074d-a7f3-4972-9c37-96b490a4dd96
img
src
<input type="file" />
6pp0gazn3#
TLDR:这解释了如何在没有redux的情况下通过在typescript中使用react context来解决问题(如果你喜欢js,你可以返回just convert it)。希望这没有错过太多的主题,因为我也是偶然发现这个线程的。
在表单中处理文件上传的特定情况下,我建议不要使用状态管理器(非序列化数据),而使用react context。这样你就可以放弃文件/文件数组(多上传),并在任何你需要的地方使用它们(在ofc提供者的范围内),而不必将 prop 钻到所需的组件中。我相信还有其他方法可以解决这个问题,但是我使用react上下文的次数越多,我就越了解事情是如何在后台工作的,并且与状态管理器相比,使用原则感觉就像是一箭之遥。但是让我们记住,有一个稍微不同的需求范围,因为我们想要上传一些文件并将其存储在浏览器中,甚至在发送之前预览,就像#jetpackpony描述的那样,然后下面就方便了:想象一下,我们想要用上下文 Package 一个对话框组件,这样子组件就可以接收和处理其父组件范围内的数据。
DialogContextProvider.tsx
import { createContext, useMemo, useState } from 'react' interface DialogContextValues { attachments: File[] setAttachments: React.Dispatch<React.SetStateAction<File[]>> } export const DialogContext = createContext<DialogContextValues | undefined>(undefined) const DialogContextProvider = ({ children }: { children: JSX.Element }) => { const [attachments, setAttachments] = useState<File[]>([]) const dialogContextValue = useMemo( () => ({ attachments, setAttachments }), [attachments, setAttachments], ) return <DialogContext.Provider value={dialogContextValue}>{children}</DialogContext.Provider> } export default DialogContextProvider
字符串
作为组件的父组件,然后可以获取/设置它的数据。SomeUIComponent.tsx
import DialogContextProvider from './DialogContextProvider' export const SomeUIComponent = () => ( <div> <h2>This is out of context</h2> <DialogContextProvider> <SomeComponentWhichUsesContext /> <AnotherComponentWhichUsesContext /> </DialogContextProvider> </div> )
型
此外,我们可以使用自定义钩子来检索数据,使代码更加精简。useDialogContext.ts
import { useContext } from 'react' import { DialogContext } from './DialogContextProvider' // Custom hook to access the created context const useDialogContext = () => { const context = useContext(DialogContext) const attachments = context?.attachments || [] const setAttachments = context?.setAttachments || (() => []) if (!context) { throw new Error('useDialogContext must be used within a Dialog') } return { attachments, setAttachments } } export default useDialogContext
型稍后,您可以像这样使用传递给上下文的值
const { attachments, setAttachments } = useDialogContext()
请注意,在应用的较小范围内,你应该只喜欢react context而不是状态管理器,因为它可能会触发比配置良好的状态管理器更多的重新呈现,并且缺乏单向数据流和可预测的集中状态等良好功能。
3条答案
按热度按时间bbuxkriu1#
Redux的关键规则之一是不可序列化的值不应该进入存储。因此,如果可能的话,文件对象不应该保留在Redux存储中。
aemubtdh2#
我遇到了类似的问题,最后使用了这个:
字符串
它返回一个类似
blob:http://example.com/f331074d-a7f3-4972-9c37-96b490a4dd96
的url,它只是一个字符串,可以在img
标签的src
属性中使用。不确定Material Ui dropzone返回什么,但这适用于<input type="file" />
返回的File对象6pp0gazn3#
TLDR:这解释了如何在没有redux的情况下通过在typescript中使用react context来解决问题(如果你喜欢js,你可以返回just convert it)。希望这没有错过太多的主题,因为我也是偶然发现这个线程的。
在表单中处理文件上传的特定情况下,我建议不要使用状态管理器(非序列化数据),而使用react context。这样你就可以放弃文件/文件数组(多上传),并在任何你需要的地方使用它们(在ofc提供者的范围内),而不必将 prop 钻到所需的组件中。
我相信还有其他方法可以解决这个问题,但是我使用react上下文的次数越多,我就越了解事情是如何在后台工作的,并且与状态管理器相比,使用原则感觉就像是一箭之遥。但是让我们记住,有一个稍微不同的需求范围,因为我们想要上传一些文件并将其存储在浏览器中,甚至在发送之前预览,就像#jetpackpony描述的那样,然后下面就方便了:
想象一下,我们想要用上下文 Package 一个对话框组件,这样子组件就可以接收和处理其父组件范围内的数据。
创建上下文并导出我们的提供程序:
DialogContextProvider.tsx
字符串
设置上下文
作为组件的父组件,然后可以获取/设置它的数据。
SomeUIComponent.tsx
型
context hook使用
此外,我们可以使用自定义钩子来检索数据,使代码更加精简。
useDialogContext.ts
型
稍后,您可以像这样使用传递给上下文的值
型
请注意,在应用的较小范围内,你应该只喜欢react context而不是状态管理器,因为它可能会触发比配置良好的状态管理器更多的重新呈现,并且缺乏单向数据流和可预测的集中状态等良好功能。