How to Implement Cloudinary Upload Widget in React?

…衆ロ難τιáo~ 提交于 2020-01-14 14:13:22

问题


I'm trying to use the Cloudinary Upload Widget in my React App but i have a problem. When running the project, the Upload Widget appears immediately, but when closed and opened again, the app crashes and displays the following message:

widget.open() is not a function

Note: The upload works correctly

import React, { Component } from 'react';
import './App.css';

class App extends Component {
  showWidget = (widget) => {
    widget.open();
  }

  checkUploadResult = (resultEvent) => {
    if(resultEvent.event === 'success'){
      console.log(resultEvent)
    }
  }
  render() {
      let widget = window.cloudinary.openUploadWidget({
      cloudName: "*********",
      uploadPreset: "tryingfirsttime"},
      (error, result) => {this.checkUploadResult(result)});

    return (
      <div className="App">
        <button onClick={this.showWidget}> Upload file</button>
      </div>
    );
  }
}

export default App;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<script src="https://widget.cloudinary.com/v2.0/global/all.js" type="text/javascript"></script> 

enter image description here

enter image description here


回答1:


First, let's understand the issue. The Cloudinary upload widget is defined in the render function of the component and when that component is rendered, it will open the upload widget since it's defined with the functionality of openUploadWidget. Secondly, the widget is defined only in the scope of the render function and not accessible outside of it, hence the error widget.open() is not a function.

To remedy these issues, I would first start by defining the widget either as a local variable or part of the state. This is done by including the constructor as part of your component:

constructor(props) {
   super(props)

   // Defined in state
   this.state = { . . . }

   // Defined as local variable
   this.widget = myLocalVariable
}

The next thing to do is when creating an instance of the Cloudinary upload widget, to use createUploadWidget and not openUploadWidget, to allow control of when to open the widget.

constructor(props) {
   super(props)
   // Defined in state
   this.state = {
      widget: cloudinary.createUploadWidget({
         cloudName: 'my_cloud_name', 
         uploadPreset: 'my_preset'}, 
         (error, result) => { 
            if (!error && result && result.event === "success") { 
               console.log('Done! Here is the image info: ', result.info); 
            }
         }
      })
    }
    // Defined as local variable
    this.widget = cloudinary.createUploadWidget({
       cloudName: 'my_cloud_name', 
       uploadPreset: 'my_preset'}, (error, result) => { 
         if (!error && result && result.event === "success") { 
           console.log('Done! Here is the image info: ', result.info); 
         }
       }
    })
 }

Lastly, the showWidget click event does not need the widget passed as an argument (since it's defined locally in the component) and can be referred too with the this keyword. Note that you'll need to include the keyword this to refer to the current component.

showWidget = () => {
  this.widget.open();
}

I have included a JSFiddle showing the end result: https://jsfiddle.net/danielmendoza/fve1kL53/



来源:https://stackoverflow.com/questions/55292306/how-to-implement-cloudinary-upload-widget-in-react

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!