繁体   English   中英

如何让 my.js 文件在 React 中呈现 .html 文件?

[英]How do I get my .js file to render an .html file in React?

我一直在尝试在我的网站上实现一个 S3 存储桶,以将上传的图像存储到亚马逊的云中。 为此,需要一些 HTML 样板。 我制作了一个 HTML 文件并复制了样板文件,现在想在 my.js 文件上使用它,其中包含我希望显示此信息的网页。

这是 HTML 文件:

<html>
  <body>

    <h1>Edit your account</h1>

    <hr>

    <h2>Your avatar</h2>

    <input type="file" id="file-input">
    <p id="status">Please select a file</p>
    <img style="border:1px solid gray;width:300px;"  id="preview" src="/images/default.png">

    <h2>Your information</h2>

    <form method="POST" action="/save-details">
      <input type="hidden" id="avatar-url" name="avatar-url" value="/images/default.png">
      <input type="text" name="username" placeholder="Username"><br>
      <input type="text" name="full-name" placeholder="Full name"><br><br>

      <hr>
      <h2>Save changes</h2>

      <input type="submit" value="Update profile">
    </form>


    <script>

    /*
      Function to carry out the actual PUT request to S3 using the signed request from the app.
    */
    function uploadFile(file, signedRequest, url){
      const xhr = new XMLHttpRequest();
      xhr.open('PUT', signedRequest);
      xhr.onreadystatechange = () => {
        if(xhr.readyState === 4){
          if(xhr.status === 200){
            document.getElementById('preview').src = url;
            document.getElementById('avatar-url').value = url;
          }
          else{
            alert('Could not upload file.');
          }
        }
      };
      xhr.send(file);
    }

    /*
      Function to get the temporary signed request from the app.
      If request successful, continue to upload the file using this signed
      request.
    */
    function getSignedRequest(file){
      const xhr = new XMLHttpRequest();
      xhr.open('GET', `/sign-s3?file-name=${file.name}&file-type=${file.type}`);
      xhr.onreadystatechange = () => {
        if(xhr.readyState === 4){
          if(xhr.status === 200){
            const response = JSON.parse(xhr.responseText);
            uploadFile(file, response.signedRequest, response.url);
          }
          else{
            alert('Could not get signed URL.');
          }
        }
      };
      xhr.send();
    }

    /*
     Function called when file input updated. If there is a file selected, then
     start upload procedure by asking for a signed request from the app.
    */
    function initUpload(){
      const files = document.getElementById('file-input').files;
      const file = files[0];
      if(file == null){
        return alert('No file selected.');
      }
      getSignedRequest(file);
    }

    /*
     Bind listeners when the page loads.
    */
    (() => {
        document.getElementById('file-input').onchange = initUpload;
    })();

    </script>

<div id="root"></div>

  </body>

这是.js文件:

import React, { useState } from "react";
import { Typography, Button, Form, message, Input, Icon } from "antd";
import FileUpload from "../../utils/FileUpload";
import FileUploadNew from "../../utils/fileUploadNew";
import ReactDOM from 'react-dom'
import Axios from "axios";

const { Title } = Typography;
const { TextArea } = Input;
const num = 20


const Continents = [
  { key: 1, value: "MLA" },
  { key: 2, value: "APA" },
];

function UploadProductPage(props) {
  const [TitleValue, setTitleValue] = useState("");
  const [SubjectValue, setSubjectValue] = useState("");
  const [DescriptionValue, setDescriptionValue] = useState("");
  const [PriceValue, setPriceValue] = useState(0);
  const [ContinentValue, setContinentValue] = useState(1);
  const [imageData, setImageData] = useState("");


  const [Images, setImages] = useState("");

  const onTitleChange = (event) => {
    setTitleValue(event.currentTarget.value);
  };

  const onSubjectChange = (event) => {
    setSubjectValue(event.currentTarget.value);
  };

  const onDescriptionChange = (event) => {
    setDescriptionValue(event.currentTarget.value);
  };

  const onPriceChange = (event) => {
    setPriceValue(event.currentTarget.value);
  };

  const onContinentsSelectChange = (event) => {
    setContinentValue(event.currentTarget.value);
  };

  const updateImages = (newImages) => {
    setImages(newImages);
  };
  const onSubmit = (event) => {
    event.preventDefault();

    if (
      !TitleValue ||
      !SubjectValue ||
      !DescriptionValue ||
      !PriceValue ||
      !ContinentValue ||
      !Images
    ) {
      return alert("fill all the fields first!");
    }

    const variables = {
      writer: props.user.userData._id,
      title: TitleValue,
      subject: SubjectValue,
      description: DescriptionValue,
      price: PriceValue,
      images: Images,
      continents: ContinentValue,
    };

      Axios.post("/api/product/uploadProduct", variables).then((response) => {
      if (response.data.success) {
        alert("Product Successfully Uploaded");
        
      } else {
        alert("Failed to upload Product");
      }
    });
  };
  const picData = (value) => {
    setImages(value);
  };
  return (
    <div style={{ maxWidth: "700px", margin: "2rem auto" }}>
      <div style={{ textAlign: "center", marginBottom: "2rem" }}>
        <Title level={2}> Upload Prompt</Title>
      </div>

      <Form onSubmit={onSubmit}>
        {/* DropZone */}
        {/* <FileUpload refreshFunction={updateImages} /> */}
        {/* kamran's code */}
        <FileUpload imagePath={picData} refreshFunction={updateImages} />
        <br />
        <br />
        <label>Title</label>
        <Input onChange={onTitleChange} value={TitleValue} />
        <br />
        <br />
        <label>Subject</label>
        <Input onChange={onSubjectChange} value={SubjectValue} />
        <br />
        <br />
        <label>Description</label>
        <TextArea onChange={onDescriptionChange} value={DescriptionValue} />
        <br />
        <br />
        <label>Number of pages</label>
        <Input onChange={onPriceChange} value={PriceValue} type="number" />
        <br />
        <br />
        <label>Format</label>
        <br>
        </br>
        <select onChange={onContinentsSelectChange} value={ContinentValue}>
          {Continents.map((item) => (
            <option key={item.key} value={item.key}>
              {item.value}{" "}
            </option>
          ))}
        </select>
        <br />
        <br />

        <Button onClick={onSubmit}>Submit</Button>
      </Form>
    </div>
  );
}

export default UploadProductPage;

我一直在阅读并尝试使用 getdocumentbyID 但它不起作用。 没有显示错误。 任何帮助表示赞赏

React 使绑定函数变得容易,而不必先 select 然后将函数绑定到 DOM。

将您的 function 放在您的退货声明上方

  const picData = (value) => {
    setImages(value);
  };

  const uploadFile = (file, signedRequest, url) => {
    const xhr = new XMLHttpRequest();
    xhr.open('PUT', signedRequest);
    xhr.onreadystatechange = () => {
      if(xhr.readyState === 4){
        if(xhr.status === 200){
          document.getElementById('preview').src = url;
          document.getElementById('avatar-url').value = url;
        }
        else{
          alert('Could not upload file.');
        }
      }
    };
    xhr.send(file);
  }

  const getSignedRequest = (file) => {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', `/sign-s3?file-name=${file.name}&file-type=${file.type}`);
    xhr.onreadystatechange = () => {
      if(xhr.readyState === 4){
        if(xhr.status === 200){
          const response = JSON.parse(xhr.responseText);
          uploadFile(file, response.signedRequest, response.url);
        }
        else{
          alert('Could not get signed URL.');
        }
      }
    };
    xhr.send();
  }

  const initUpload = () => {
    const files = document.getElementById('file-input').files;
    const file = files[0];
    if(file == null){
      return alert('No file selected.');
    }
    getSignedRequest(file);
  }

return (
...rest of code here

在代码的 DOM 部分中,将 onChange 添加到输入

<input type="file" id="file-input" onChange={initUpload}>

你可以通过使用dangerouslySetInnerHTML作为组件中的 props 来强制 React 渲染 html。

这是一个示例实现:

hello.html

<h1>Hello world</h1>

在你的App.js

import React from "react";
import "./styles.css";
import hello from "./hello.html";

export default function App() {
  return (
    <div className="App">
      <div dangerouslySetInnerHTML={{ __html: hello }} />
    </div>
  );

在您的情况下,使用import htmlFile from './htmfile.html'像常规模块一样导入 html 文件,并将其写入带有dangerouslySetInerHTML SetInerHTML的div标签中

强制 React 在组件中渲染 native.html 文件被认为是危险的,这是有原因的。 您可能想访问此链接以了解有关 div 属性和 XSS 的更多信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM