如何发出PUT API HTTPS请求[reactJS]

时间:2019-10-01 10:06:14

标签: javascript reactjs typescript

当前正在管理控制台上进行卡片列表显示。这些卡可以是基于视频的卡,也可以是基于文本的卡,具体取决于发送给它的URL。该API在本地托管,并传递诸如id,Title,URL,ThumbnailURL之类的信息。我创建了一个成功的删除方法,该方法可以从API中删除卡。我有两个模块,HelpCard.tsx和HelpList.tsx。

具有deleteProduct和EditProduct功能的代码位于HelpList.tsx上,如下所示:

import React, { Component } from "react";
import HelpCard from "./HelpCard";
import "../help/HelpCard.css";
import axios from "axios";
import InfiniteScroll from "react-infinite-scroller";
import { Button } from "components/ui";

interface State {
  url: string;
  title: string;
  adminhelpcard: SingleAdminHelpCard[];
  error: null;
  response: {};
  thumbnail: string;
}

interface SingleAdminHelpCard {
  id: string;
  url: string;
  title: string;
  thumbnail: string;
}

interface Props {}

export default class HelpList extends Component<Props, State> {
  state = {
    title: "",
    thumbnail: "",
    id: "",
    url: "http://localhost:3000/videos/",
    adminhelpcard: [],
    itemsCountPerPage: 1,
    activePage: 1,
    error: null,
    response: {}
  };

  loadAdminHelpCard = () => {
    axios
      .get(this.state.url)
      .then((res) => {
        this.setState((prevState) => {
          const adminhelpcard = prevState.adminhelpcard;
          return {
            adminhelpcard: [...prevState.adminhelpcard, ...res.data],
            url: res.data.next
          };
        });
      })
      .catch(function(error) {
        // handle error
        console.log(error);
      });
  };
  static props: any;

  async componentDidMount() {
    const apiUrl = "http://localhost:3000/videos/";
    const res = await axios.get(this.state.url);
    this.setState({ adminhelpcard: res.data });
    fetch(apiUrl)
      .then((res) => res.json())
      .then(
        (result) => {
          this.setState({
            adminhelpcard: result
          });
        },
        (error) => {
          this.setState({ error });
        }
      );
  }

  deleteProduct(id: any) {
    const { adminhelpcard } = this.state;

    const apiUrl = `http://localhost:3000/videos/${id}`;

    const options = {
      method: "DELETE"
    };

    fetch(apiUrl, options)
      .then((res) => res.json())
      .then(
        (result) => {
          this.setState({
            response: result,
            adminhelpcard: adminhelpcard.filter((adminhelpcard: SingleAdminHelpCard) => adminhelpcard.id !== id)
          });
        },
        (error) => {
          this.setState({ error });
        }
      );

    console.log(this.state.id);
  }

  editProduct(id: any) {
    const formData = new FormData();
    const { adminhelpcard } = this.state;

    const apiUrl = `http://localhost:3000/videos/${id}`;

    const options = {
      method: "PUT"
    };
    formData.append("textCardTitle", this.state.title);
    formData.append("textCardURL", this.state.url);
    formData.append("textCardThumbnail", this.state.thumbnail);

    return fetch("http://localhost:3000/videos/${id}", {
      method: "POST",
      body: formData
    }).then((response) => response.json());
  }

  render() {
    console.log(this.state.adminhelpcard);
    return (
      <div>
        <React.Fragment>
          {this.state.adminhelpcard ? (
            <div className="row">
              <InfiniteScroll
                pageStart={1}
                loadMore={this.loadAdminHelpCard}
                hasMore={this.state.url ? true : false}
                threshold={0}
                loader={
                  <div className="loader" key={0}>
                    Loading ...
                  </div>
                }>
                {this.state.adminhelpcard.map((adminhelpcard: SingleAdminHelpCard, i) => (
                  <HelpCard
                    id={adminhelpcard.id}
                    key={adminhelpcard.id + i}
                    title={adminhelpcard.title}
                    url={adminhelpcard.url}
                    thumbnail={adminhelpcard.thumbnail}
                    deleteProduct={this.deleteProduct.bind(this)}
                    editProduct={this.editProduct.bind(this)}
                  />
                ))}
              </InfiniteScroll>
            </div>
          ) : (
            <h1>Loading Cards</h1>
          )}
        </React.Fragment>
      </div>
    );
  }
}

提交请求的代码在HelpCard.tsx上。我已经在从HelpList.tsx调用的卡的编辑/删除按钮中设置了一个OnClick。尽管“删除”按钮有效,但编辑似乎不能很好地工作,我不确定为什么。单击提交编辑按钮似乎只是刷新页面。代码如下:

import React, { Component } from "react";
import "../help/HelpCard.css";
import "../help/HelpList";
import Dialog from "../help/Dialog";
import Popup from "reactjs-popup";

interface Props {
  id: string;
  url: string;
  title: string;
  thumbnail: string;
  deleteProduct: (id: any) => void;
  editProduct: (id: any) => void;
}
/**/

interface State {
  title: string;
  thumbnail: string;
  id: string;
  url: string;
  imageLoading?: boolean;
  tooManyRequests?: boolean;
  _input?: HTMLInputElement;
}

export default class HelpCard extends Component<Props, State> {
  state = {
    url: "",
    id: "",
    title: "",
    imageLoading: true,
    tooManyRequests: false,
    thumbnail: ""
  };

  componentDidMount() {
    const { url, title, thumbnail } = this.props;
    const id = url.split("/")[url.split("/").length - 2];

    this.setState({
      url,
      id,
      title,
      thumbnail,
      imageLoading: true,
      tooManyRequests: false
    });
  }

  render() {
    const isThumbnail = this.state.thumbnail;
    const adminhelpcard = this.state;
    return (
      <React.Fragment>
        <div>
          {isThumbnail ? (
            <div className="horizontalCard">
              <div className="innerCard">
                <div className="leftImage">
                  <img
                    className="Sprite"
                    onLoad={() => this.setState({ imageLoading: false })}
                    onError={() => this.setState({ tooManyRequests: true })}
                    src={this.state.thumbnail}
                    style={
                      this.state.tooManyRequests
                        ? { display: "none" }
                        : this.state.imageLoading
                        ? { display: "null" }
                        : { display: "null" }
                    }
                  />
                </div>
                <div className="rightText">
                  <div className="card-body">
                    {this.state.title}
                    <div className="cardButtons">
                      <Popup trigger={<button className="btn"> Edit</button>} position="right center">
                        <form id="videoCardEdit" style={{ width: "auto", height: "auto" }}>
                          <div>
                            <div>
                              <label>Title:</label>
                              <input id="videoCardTitle" defaultValue={this.state.title}></input>
                            </div>
                            <div>
                              <label>URL:</label>
                              <input id="videoCardURL" defaultValue={this.state.url}></input>
                            </div>
                            <div>
                              <label>Thumbnail URL:</label>
                              <input id="videoCardThumbnail" defaultValue={this.state.thumbnail}></input>
                            </div>
                          </div>
                          <button onClick={() => this.props.editProduct(this.props.id)} id="confirmModalBtn">
                            confirm
                          </button>
                          <button id="cancelModalBtn">cancel</button>
                        </form>
                      </Popup>
                      <button onClick={() => this.props.deleteProduct(this.props.id)} className="btn">
                        Delete
                      </button>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          ) : (
            <div className="styledLink" to={`adminhelpcard/${this.state.id}`}>
              <div className="card">
                <div>
                  {this.state.tooManyRequests ? (
                    <h6 className="mx-auto">
                      <span className="badge badge-danger mt-2"></span>
                    </h6>
                  ) : null}
                  <div className="card-body mx-auto">
                    <div className="card-title">
                      {this.state.title
                        .toLowerCase()
                        .split(" ")
                        .map((letter) => letter.charAt(0).toUpperCase() + letter.substring(1))
                        .join(" ")}
                      <div className="cardButtons">
                        <Popup trigger={<button className="btn"> Edit</button>} position="right center">
                          <form id="textCardEdit" style={{ width: "auto", height: "auto" }}>
                            <div>
                              <div>
                                <label>Title:</label>
                                <input id="textCardTitle" defaultValue={this.state.title}></input>
                              </div>
                              <div>
                                <label>URL:</label>
                                <input id="textCardURL" defaultValue={this.state.url}></input>
                              </div>
                              <div>
                                <label>Thumbnail URL:</label>
                                <input id="textCardThumbnail" defaultValue={this.state.thumbnail}></input>
                              </div>
                            </div>
                            <button id="confirmModalBtn">confirm</button>
                            <button id="cancelModalBtn">cancel</button>
                          </form>
                        </Popup>
                        <button onClick={() => this.props.deleteProduct(this.props.id)} className="btn ">
                          Delete
                        </button>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          )}
        </div>
      </React.Fragment>
    );
  }
}

单击编辑按钮将打开一个模式对话框,其中将当前卡片的URL,标题和缩略图加载到输入中。我试图这样做,以便对输入进行任何更改,管理员可以单击“提交”,它将更改API上的url /标题/缩略图。

我的代码中缺少什么吗?

1 个答案:

答案 0 :(得分:3)

form标签会将提交时的页面重定向到指定的目标。

防止在提交操作时使用form标签的默认操作。

<form onSubmit={e => e.preventDefault()} id="textCardEdit" style={{ width: "auto", height: "auto" }}>

您可以了解有关form标签here的更多信息。