使用 ReactJS 上传图片

Posted

技术标签:

【中文标题】使用 ReactJS 上传图片【英文标题】:Image upload with ReactJS 【发布时间】:2017-08-03 03:20:12 【问题描述】:

我正在构建这个 ReactJS 应用程序,我想在其中通过单击按钮上传图像并将其带到下一个视图,即裁剪窗口,然后在裁剪后将其上传到服务器.

我现在遇到的问题是如何将图像从一个视图带到另一个视图而不将其上传到服务器?

我尝试获取图像路径,但不幸的是,当 UI 刷新时,路径会被刷新。

那么,在这种情况下我可以使用哪些选项。

谢谢!

【问题讨论】:

将图像读取为 data-uri 而不是仅仅保留其路径。此外,如果您想在刷新期间将图像持久保存,您可以将图像存储在本地存储中。 尝试像npmjs.com/package/blob-util这样的库来处理图像到数据的转换以进行存储等。 【参考方案1】:

昨天我处理了类似的案例。我正在使用返回上传文件的 react-dropzone,文件对象中的一个字段是“预览”,它包含当前上传文件的 uri(它可能以某种方式缓存,但我还没有调查它)。 在另一个视图中你只是在做

【讨论】:

【参考方案2】:

因此,您希望在视图之间保留图像信息。 “视图”是指不同的 html 页面吗?我想一个更标准的做事方式是:

将文件内容/路径存储在某个状态(例如 redux 状态) 使用客户端路由器(例如 react-router)在保持状态的同时更改视图

如果你从未使用过客户端路由,它看起来像这样(使用 react-router):

import  Router, Route, browserHistory  from 'react-router'

// Iy you use redux to handle the state
import  createStore  from 'redux'
import myReducer from 'my-reducer'
const store = createStore(myReducer) 
const history = syncHistoryWithStore(browserHistory, store)

// Your view components
function Top(props)  ... 
function UploadImage(props)  ... 
function EditImage(props)  ... 

// The Router itself
ReactDOM.render(
  <Router history=history>
    <Route path="/" component=Top >
      <Route path="upload-image" component=UploadImage />
      <Route path="edit-image" component=EditImage />
    </Route>
  </Router>)

如果你之前没用过redux,可以这样使用:

首先,创建reducer

import  combineReducers  from 'redux'

const myReducer = combineReducers( imagePath )

// This is called a reducer function
function imagePath(oldState = "", action) 
  switch(action.type) 
  case 'SET_PATH':
    return action.payload
  

接下来,连接您的组件以获取状态值(例如 UploadImage)

const ReduxUploadImage = connect(function(state) 
  return 
    imagePath: state.imagePath
  
)(UploadImage)

现在,如果您使用ReduxUploadImage 而不是UploadImage,则可以通过props.imagePath 访问imagePathconnect 函数还会为你的 props 添加一个 dispatch 函数。

最后,您可以通过在组件中调用来设置路径(但不是渲染函数本身:这将是一个anti-pattern)

props.dispatch(  type: 'SET_PATH', payload: "the_path"  )

最后,使用dedicated middleware可以很容易地保持页面之间的redux状态或刷新。

【讨论】:

【参考方案3】:

IndexedDB API 非常适合客户端、大文件存储。

Using IndexedDB: MDN

结帐LocalForage。它使 IndexedDB 的使用变得简单,类似于使用 localStorage

此解决方案将允许您使用所有主要浏览器存储图像客户端。您可以从全局存储对其执行操作,并且可以在需要时将其发送到服务器。

它还为您的应用程序提供离线缓存,其中图像不会在会话或网络连接之间丢失。

【讨论】:

【参考方案4】:

您需要将图像文件作为 blob 读取,并将其保存在负责渲染不同组件以进行图像操作的父组件上。在某些文件输入元素中,您需要这样的函数来处理用户选择的图像

  handleImageChange = e => 
    e.preventDefault();

    const reader = new FileReader();
    const file = e.target.files[0];

    reader.onloadend = () => 
        this.setState(
            file,
            imagePreview: reader.result
        );
    ;

    if (file) 
        reader.readAsDataURL(file);
    
  ;

然后,您可以将该文件放在任意数量的组件上。如果您希望它在刷新之间保持不变,您需要将文件放在 localStorage 或 indexedDB 上

【讨论】:

以上是关于使用 ReactJS 上传图片的主要内容,如果未能解决你的问题,请参考以下文章

ref 不是函数,firebase 存储图片上传,reactJS

如何直接在云端上传图片而不将其存储到本地目录中?

React JS文件上传

使用webuploader插件上传图片时如果正确 限制上传数量

vue移动端图片上传,可最多上传9张,使用webuploader插件

原生方式实现图片,文件上传,和使用ElmentUI使用Drag方式自动上传图片,手动上传图片