Get image preview before uploading in React

前端 未结 9 1690
醉梦人生
醉梦人生 2020-12-04 17:51

Many examples of this on here but can\'t seem to find any for react. I have managed to convert the vanilla js to react but getting an error.

The answer looks simple

相关标签:
9条回答
  • 2020-12-04 18:30

    I had a crazy time trying to get this to work with multiple files, so if anyone else is having this problem, here you go:

    const onFileChange = e => {
    e.preventDefault();
    const filesList = e.target.files;
    
    if (filesList.length === 0) return;
    //Spread array to current state preview URLs
    let arr = [...data.imagePreviewUrls];
    for (let i = 0; i < filesList.length; i++) {
      const file = filesList[i];
    
      const reader = new FileReader();
      reader.onload = upload => {
        //push new image to the end of arr
        arr.push(upload.target.result);
        //Set state to arr
        setData({
          ...data,
          imagePreviewUrls: arr
        });
      };
      reader.readAsDataURL(file);
    }
    };
    

    Essentially the for loop resolves before even the first onload event fires, resetting the state every time it iterates. To resolve this just make an array outside of the for loop and push the new item to it onload. This will handle multiple files even if the user closes the file dialog and later chooses to upload more, as long as state hasn't been reset.

    0 讨论(0)
  • 2020-12-04 18:31

    -- Constructor

    constructor(props) {
      super(props);
      this.state = {
         imgRef: ""
      };
    }
    

    -- Function

    filePreview(e) {
        const file = e.target.files[0];
        this.setState({
            imgRef: URL.createObjectURL(file)
        });
    }
    

    -- Html

    <input
       type="file"
       name="photo"
       onChange={this.fileSelectHandler.bind(this)}
    />
    <img src={this.state.imgRef} />
    
    0 讨论(0)
  • 2020-12-04 18:38

    No difference, just read your image when the load event finishes. After the load end event handler just set your state:

    getInitialState: function(){
      return{file: []}
    }
    
    _onChange: function(){
      // Assuming only image
      var file = this.refs.file.files[0];
      var reader = new FileReader();
      var url = reader.readAsDataURL(file);
    
       reader.onloadend = function (e) {
          this.setState({
              imgSrc: [reader.result];
          })
        }.bind(this);
      console.log(url) // Would see a path?
      // TODO: concat files
    },
    
    render: function(){
     return(
      <div>
        <form>
          <input 
            ref="file" 
            type="file" 
            name="user[image]" 
            multiple="true"
            onChange={this_onChange}/>
         </form>
        {/* Only show first image, for now. */}
        <img src={this.state.imgSrc} />
      </div>
     )
    }
    
    0 讨论(0)
  • 2020-12-04 18:40

    You can use base64 and use that result in the img src. Here I am using typescript, but you can use the same logic with pure JS

    (file: Blob):Promise< string | ArrayBuffer | null> => new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = () => resolve(reader.result);
        reader.onerror = error => reject(error);
    }),
    
    0 讨论(0)
  • 2020-12-04 18:46

    There is my solution. Very simple and easy to use.

    JSX

    <form onSubmit={this.onSubmit} >      
          <input
             ref="uploadImg"
             type="file"
             name="selectedFile"
             onChange={this._onChange}
            />
    </form>
    
    <img src={this.state.imageUrl} />
    

    And function

      _onChange = (e) => {
    
        const file    = this.refs.uploadImg.files[0]
        const reader  = new FileReader();
    
        reader.onloadend = () => {
            this.setState({
                imageUrl: reader.result
            })
        }
        if (file) {
            reader.readAsDataURL(file);
            this.setState({
                imageUrl :reader.result
            })
        } 
        else {
            this.setState({
                imageUrl: ""
            })
        }
    }
    

    And of course You need to have state like imageUrl which is our src in jsx.

    0 讨论(0)
  • 2020-12-04 18:47

    URL.createObjectURL(file) short and fine solution

    0 讨论(0)
提交回复
热议问题