Reactjs应用未在野生动物园中显示图像预览

问题描述 投票:0回答:1

我正在尝试制作一个用户可以上传图像并将其发送给电子邮件的应用程序,该应用程序在除Safari之外的所有浏览器上均能正常工作。对于移动浏览器和Web浏览器,当我选择要上传的图像时,似乎没有任何预览,甚至没有加载(准备发送)。有什么我可以解决的吗?我的代码非常简单:

const EnterDetailPage = props => {
  const [imageUrl, setImageUrl] = useState("");
  const [imageFile, setImageFile] = useState();
  const [upload, setUpload] = useState(null);
const handleUploadChange = async e => {
    setLoading(true);
    const file = e.target.files[0];
    if (!file) {
      return;
    }
    setUpload(URL.createObjectURL(file));
    setImageFile(file);
    const ref = firebase
      .storage()
      .ref()
      .child(uuid.v4());

    const snapshot = await ref.put(file);
    let getImageUrl = await snapshot.ref.getDownloadURL();
    setImageUrl(getImageUrl);
    setLoading(false);
    console.log(getImageUrl);
  };
  let imgPreview = null;
    if (upload) {
    imgPreview = (
      <Avatar
        variant="square"
        src={upload}
        alt="Avatar"
        className={classes.bigAvatar}
      />
    );
  }
  return(
<div className="m-auto p-16 sm:px-24 sm:mx-auto max-w-xl">
        <input
          accept="image/jpeg,image/gif,image/png"
          className="hidden"
          id="button-file"
          type="file"
          // onChange={handleUploadChange}
          onInput={handleUploadChange}
          onClick={event => {
            event.target.value = null;
          }}
        />
        <label
          htmlFor="button-file"
          className={`${classes.bigAvatar} mt-8 bg-gray-300 m-auto flex items-center justify-center relative w-128 h-128 rounded-4 a-mr-16 a-mb-16 overflow-hidden cursor-pointer shadow-1 hover:shadow-xl`}
        >
          <div className="absolute flex items-center justify-center w-full h-full z-50">
          {imageUrl ? null :
            <Icon fontSize="large" color="primary" className="cloud-icon">
              cloud_upload
            </Icon>}
          </div>
          {imgPreview}
        </label>
);
}:

我将代码与本文的代码进行了比较:https://w3path.com/react-image-upload-or-file-upload-with-preview/

似乎我已经做了完全相同的事情...为什么我没有得到相同的结果?

reactjs safari
1个回答
0
投票
Safari似乎不支持尝试使用input事件侦听器的onInput元素-回调从未执行。相反,您可以使用onChange事件侦听器。

对于下面的示例,我通过设置带有超时的Promise来伪造API调用,但这不是必需的,仅用于演示目的。另外,我喜欢在多个单独的状态上使用对象,尤其是在状态需要同步的情况下-它更干净,更易于阅读,并且功能更像基于class的组件。


演示:https://jd13t.csb.app/

来源

Edit Image Upload Preview


components / DetailPage.js

import React, { useRef, useState } from "react"; import { CircularProgress, Icon, Fab } from "@material-ui/core"; const initialState = { isLoading: false, imageName: "", imagePreview: null, imageSize: 0 }; const EnterDetailPage = () => { const [state, setState] = useState(initialState); const uploadInputEl = useRef(null); const handleUploadChange = async ({ target: { files } }) => { setState(prevState => ({ ...prevState, isLoading: true })); const file = files[0]; await new Promise(res => { setTimeout(() => { res( setState(prevState => ({ ...prevState, imageName: file.name, imagePreview: URL.createObjectURL(file), imageSize: file.size, isLoading: false })) ); }, 2000); }); }; const resetUpload = () => { setState(initialState); uploadInputEl.current.value = null; }; const uploadImage = async () => { if (state.imagePreview) setState(prevState => ({ ...prevState, isLoading: true })); await new Promise(res => { setTimeout(() => { res(alert(JSON.stringify(state, null, 4))); resetUpload(); }, 2000); }); }; const { imagePreview, imageName, imageSize, isLoading } = state; return ( <div style={{ padding: 20 }}> <div style={{ textAlign: "center" }}> <div> <input accept="image/jpeg,image/gif,image/png" className="hidden" id="button-file" type="file" ref={uploadInputEl} onChange={handleUploadChange} /> <label htmlFor="button-file"> <div> {imagePreview ? ( <> <img src={imagePreview} alt="Avatar" style={{ margin: "0 auto", maxHeight: 150 }} /> <p style={{ margin: "10px 0" }}> ({imageName} - {(imageSize / 1024000).toFixed(2)}MB) </p> </> ) : ( <Icon fontSize="large" color="primary" className="cloud-icon"> cloud_upload </Icon> )} </div> </label> <Fab variant="extended" size="large" color="primary" aria-label="add" className="" type="button" onClick={uploadImage} > {isLoading ? ( <CircularProgress style={{ color: "white" }} /> ) : ( "Submit" )} </Fab> {imagePreview && ( <Fab variant="extended" size="large" color="default" aria-label="add" className="" type="button" onClick={resetUpload} > Cancel </Fab> )} </div> </div> </div> ); }; export default EnterDetailPage;

© www.soinside.com 2019 - 2024. All rights reserved.