reactjs 在React Redux商店中存储文件对象的最佳方式(文件从DropZone上传?)

nhhxz33t  于 2024-01-07  发布在  React
关注(0)|答案(3)|浏览(108)

我目前正在使用Material Ui dropzone上传多个文件。只是想知道在Redux商店中添加/更新文件的最佳方法是什么。我目前正在执行一个调度操作,当“onChange”触发器返回dropzone上的所有文件时,并通过存储具有files对象的整个files数组来更新Redux状态。
请告诉我是否有最好的方法来处理这件事。

bbuxkriu

bbuxkriu1#

Redux的关键规则之一是不可序列化的值不应该进入存储。因此,如果可能的话,文件对象不应该保留在Redux存储中。

aemubtdh

aemubtdh2#

我遇到了类似的问题,最后使用了这个:

URL.createObjectURL(file)

字符串
它返回一个类似blob:http://example.com/f331074d-a7f3-4972-9c37-96b490a4dd96的url,它只是一个字符串,可以在img标签的src属性中使用。不确定Material Ui dropzone返回什么,但这适用于<input type="file" />返回的File对象

6pp0gazn

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>
)

context hook使用

此外,我们可以使用自定义钩子来检索数据,使代码更加精简。
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而不是状态管理器,因为它可能会触发比配置良好的状态管理器更多的重新呈现,并且缺乏单向数据流和可预测的集中状态等良好功能。

相关问题