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

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

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

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

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

谢谢!

【问题讨论】:

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

标签: reactjs image-uploading


【解决方案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 上

        【讨论】:

          猜你喜欢
          • 2020-11-13
          • 2019-12-31
          • 1970-01-01
          • 2022-07-17
          • 1970-01-01
          • 2021-05-09
          • 2022-11-30
          • 1970-01-01
          • 2019-03-09
          相关资源
          最近更新 更多