【问题标题】:Preview of uploaded image in React js using React hooks使用 React 钩子在 React js 中预览上传的图像
【发布时间】:2021-10-05 19:21:07
【问题描述】:

使用React hooks如何在通过选择文件输入上传图像后预览previewProfilePic > img区域下的图像。

import React, { useState } from "react";

  const Register = () => {
  const [picture, setPicture] = useState(null);

  const onChangePicture = e => {
    console.log('picture: ', picture);
    setPicture(e.target.files[0]);
};
  return (
    <div className="register_wrapper">
      <div className="register_player_column_layout_one">
        <div className="register_player_Twocolumn_layout_two">
          <form className="myForm">
            <div className="formInstructionsDiv formElement">
              <h2 className="formTitle" >Sign Up</h2>
              <p className="instructionsText"></p>
              <div className="register_profile_image">
                 <input id="profilePic" type="file" onChange={onChangePicture}/>
              </div>
              <div className="previewProfilePic" >
                <img className="playerProfilePic_home_tile"  src=""></img>
              </div>
            </div>
            <div className="fillContentDiv formElement">
              <div className="names formContentElement">
                <input className="inputRequest " type="text" placeholder="First Name" />
                <input className="inputRequest " type="text" placeholder="Last Name" />
              </div>
            </div>
            <div className="submitButtonDiv formElement">
              <button className="submitButton">Register</button>
            </div>
          </form>
        </div>
      </div>
    </div>
  );
}

export default Register;

<div className="register_profile_image">
  <input id="profilePic" type="file" onChange={onChangePicture}/>
</div>

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    为了查看预览,您需要读取图像并使用接收到的 base64 格式数据设置状态并将其呈现为图像标记源。

    要读取文件数据,您可以使用FileReader

    export default () => {
      const [picture, setPicture] = useState(null);
      const [imgData, setImgData] = useState(null);
      const onChangePicture = e => {
        if (e.target.files[0]) {
          console.log("picture: ", e.target.files);
          setPicture(e.target.files[0]);
          const reader = new FileReader();
          reader.addEventListener("load", () => {
            setImgData(reader.result);
          });
          reader.readAsDataURL(e.target.files[0]);
        }
      };
      return (
        <div className="register_wrapper">
          <div className="register_player_column_layout_one">
            <div className="register_player_Twocolumn_layout_two">
              <form className="myForm">
                <div className="formInstructionsDiv formElement">
                  <h2 className="formTitle">Sign Up</h2>
                  <p className="instructionsText" />
                  <div className="register_profile_image">
                    <input id="profilePic" type="file" onChange={onChangePicture} />
                  </div>
                  <div className="previewProfilePic">
                    <img className="playerProfilePic_home_tile" src={imgData} />
                  </div>
                </div>
                <div className="fillContentDiv formElement">
                  <div className="names formContentElement">
                    <input
                      className="inputRequest "
                      type="text"
                      placeholder="First Name"
                    />
                    <input
                      className="inputRequest "
                      type="text"
                      placeholder="Last Name"
                    />
                  </div>
                </div>
                <div className="submitButtonDiv formElement">
                  <button className="submitButton">Register</button>
                </div>
              </form>
            </div>
          </div>
        </div>
      );
    };
    

    Working Demo

    【讨论】:

    • 谢谢你,伙计,但我收到一个错误..第一次上传看起来不错,尝试第二次上传而不选择文件(即点击取消)发生异常..
    • @soccerway 我更新了答案。您需要检查是否存在 e.target.files[0]
    【解决方案2】:

    我还没有对此进行测试,但是,您需要做的是通过执行此操作将文件转换为 URL => URL.createObjectURL(event.target.files[0])

    import React, { useState } from "react";
    
    const Register = () => {
      const [picture, setPicture] = useState('');
    
      const onChangePicture = e => {
        console.log('picture: ', picture);
        setPicture(URL.createObjectURL(e.target.files[0]));
      };
    
      return (
        <div className="register_wrapper">
          <div className="register_player_column_layout_one">
            <div className="register_player_Twocolumn_layout_two">
              <form className="myForm">
                <div className="formInstructionsDiv formElement">
                  <h2 className="formTitle" >Sign Up</h2>
                  <p className="instructionsText"></p>
                  <div className="register_profile_image">
                     <input id="profilePic" type="file" onChange={onChangePicture}/>
                  </div>
                  <div className="previewProfilePic" >
                    <img className="playerProfilePic_home_tile"  src={picture}></img>
                  </div>
                </div>
                <div className="fillContentDiv formElement">
                  <div className="names formContentElement">
                    <input className="inputRequest " type="text" placeholder="First Name" />
                    <input className="inputRequest " type="text" placeholder="Last Name" />
                  </div>
                </div>
                <div className="submitButtonDiv formElement">
                  <button className="submitButton">Register</button>
                </div>
              </form>
            </div>
          </div>
        </div>
      );
    }
    
    export default Register;
    

    【讨论】:

    • 谢谢,现在它正在上传文件,但我可以看到一个错误,首先你上传一张图片,图片显示成功 - 这很好。现在您再次单击选择文件,但决定不选择新图像并单击取消..异常抛出 TypeError: Failed to execute 'createObjectURL' on 'URL': 未找到与提供的签名匹配的函数。 onChangePicture C:/Project1/src/components/Register.js:10 7 |常量 onChangePicture = e => { 8 | console.log('图片:', 图片); > 10 | setPicture(URL.createObjectURL(e.target.files[0]));
    • 我尝试解决您的主要问题,“我如何预览图像”。错误消息很清楚你应该在代码中添加什么。
    【解决方案3】:

    URL.createObjectURL() 静态方法创建一个 DOMString,其中包含表示参数中给定对象的 URL。 URL 生存期与创建它的窗口中的文档相关联。新的对象 URL 表示指定的 File 对象或 Blob 对象。

    import React, { useState } from "react";
    
      const Register = () => {
      const [picture, setPicture] = useState(null);
    
      const onChangePicture = e => {
        setPicture(URL.createObjectURL(e.target.files[0]) );
    };
      return (
        <div className="register_wrapper">
          <div className="register_player_column_layout_one">
            <div className="register_player_Twocolumn_layout_two">
              <form className="myForm">
                <div className="formInstructionsDiv formElement">
                  <h2 className="formTitle" >Sign Up</h2>
                  <p className="instructionsText"></p>
                  <div className="register_profile_image">
                     <input id="profilePic" type="file" onChange={onChangePicture}/>
                  </div>
                  <div className="previewProfilePic" >
                    <img className="playerProfilePic_home_tile"  src={picture && picture}></img>
                  </div>
                </div>
                <div className="fillContentDiv formElement">
                  <div className="names formContentElement">
                    <input className="inputRequest " type="text" placeholder="First Name" />
                    <input className="inputRequest " type="text" placeholder="Last Name" />
                  </div>
                </div>
                <div className="submitButtonDiv formElement">
                  <button className="submitButton">Register</button>
                </div>
              </form>
            </div>
          </div>
        </div>
      );
    }
    
    export default Register;
    

    【讨论】:

      【解决方案4】:

      react-uploady 使这变得非常简单。 你要写的代码少了很多:

      一个非常简单的例子可以是:

      import React from "react";
      import Uploady from "@rpldy/uploady";
      import UploadButton from "@rpldy/upload-button";
      import UploadPreview from "@rpldy/upload-preview";
      
      export const App = () => (
           <Uploady destination={{ url: "my-server.com/upload" }}>     
              <UploadButton/>
              <UploadPreview
                  fallbackUrl="https://icon-library.net/images/image-placeholder-icon/image-placeholder-icon-6.jpg"/>
          </Uploady>
      );

      上传预览readme中有更多示例。

      【讨论】:

        【解决方案5】:

        你可以使用下面这个例子是你的UploadImages.js

        import React, {useState } from "react";
        import PropTypes from "prop-types";
        import FileUploadService from "./Services/FileUploadService";
        
        export const UploadImages = (props) => {
          const [currentFile, setCurrentFile] = useState("");
          const [previewImage, setPreviewImage] = useState("");
          const [progress, setProgress] = useState("");
          const [message, setMessage] = useState("");
          const [imageInfos, setImageInfos] = useState("");
        
          const componentDidMount = () => {
            FileUploadService.getFiles().then((response) => {
              setImageInfos(response.data);
            });
          };
        
          const selectFile = (event) => {
            setCurrentFile(event.target.files[0]);
            setPreviewImage(event.target.files[0]);
            setProgress(0);
            setMessage("");
          };
        
          const upload = () => {
            setProgress(0);
        
            FileUploadService.upload(currentFile, (event) => {
              setProgress(Math.round((100 * event.loaded) / event.total));
            })
              .then((response) => {
                setMessage(response.data.message);
                return FileUploadService.getFiles();
              })
              .then((files) => {
                setImageInfos(files.data);
              })
              .catch((err) => {
                setProgress(0);
                setMessage("Could not upload the image!");
                setCurrentFile("undefined");
              });
          };
        
          return (
            <div>
              <div className="row">
                <div className="col-8">
                  <label className="btn btn-default p-0">
                    <input type="file" accept="image/*" onChange={selectFile} />
                  </label>
                </div>
        
                <div className="col-4">
                  <button
                    className="btn btn-success btn-sm"
                    disabled={currentFile}
                    onClick={upload}
                  >
                    Upload
                  </button>
                </div>
              </div>
        
              {currentFile && (
                <div className="progress my-3">
                  <div
                    className="progress-bar progress-bar-info progress-bar-striped"
                    role="progressbar"
                    aria-valuenow={progress}
                    aria-valuemin="0"
                    aria-valuemax="100"
                    style={{ width: progress + "%" }}
                  >
                    {progress}%
                  </div>
                </div>
              )}
        
              {previewImage && (
                <div>
                  <img className="preview" src={previewImage} alt="" />
                </div>
              )}
        
              {message && (
                <div className="alert alert-secondary mt-3" role="alert">
                  {message}
                </div>
              )}
        
              <div className="card mt-3">
                <div className="card-header">List of Files</div>
                <ul className="list-group list-group-flush">
                  {imageInfos &&
                    imageInfos.map((img, index) => (
                      <li className="list-group-item" key={index}>
                        <a href={img.url}>{img.name}</a>
                      </li>
                    ))}
                </ul>
              </div>
            </div>
          );
        };
        
        UploadImages.propTypes = {};
        

        您的 FileUpload.js 文件如下:

        import http from "../Controllers/API/image-http";
        
        class FileUploadService {
            upload(file, onUploadProgress) {
              let formData = new FormData();
          
              formData.append("file", file);
          
              return http.post("/upload", formData, {
                headers: {
                  "Content-Type": "multipart/form-data",
                },
                onUploadProgress,
              });
            }
          
            getFiles() {
              return http.get("/files");
            }
          }
          
          export default new FileUploadService();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-10-29
          • 2019-05-12
          • 2021-02-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-04-06
          相关资源
          最近更新 更多