如何通过HTTP请求[React TS]从API删除数据

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

因此,我一直在页面的管理控制面板上工作,该页面显示了一张卡列表,单击该卡列表后,会将用户重定向到视频或基于文本的链接。我还必须添加一个CRUD功能,该功能允许我编辑/从提供的API中删除帖子。

API是本地托管的,因此请求“ localhost:3000 / videos / {Id}”将使用以下字段加载对象:“ id”,“ url”,“ title”和“ thumbnail”

我有一个用于制作卡的类,称为HelpCard.tsx,代码如下:

import React, { Component } from "react";
import "../help/HelpCard.css";
import "../help/HelpList";
import spinner from "../help/spinner.gif";
import { string, number } from "prop-types";
import { Link } from "react-router-dom";

interface Props {
  url: string;
  title: string;
  thumbnail: string;
}

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

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

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

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

  render() {
    const isThumbnail = this.state.thumbnail;
    const adminhelpcard = this.state;
    return (
      <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">
                    <button className="btn btn-update btn-outline-primary">Update</button>
                    <button
                      onClick={() => adminhelpcard.deleteProduct(this.state.id)}
                      className="btn btn-outline-primary">
                      Delete
                    </button>
                  </div>
                </div>
              </div>
            </div>
          </div>

然后我有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;
  adminhelpcard: SingleAdminHelpCard[];
  error: null;
  response: {};
}

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

interface Props {}

export default class HelpList extends Component<Props, State> {
  state = {
    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);
      });
  };

  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/${this.state.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 });
        }
      );
  }

  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
                    key={adminhelpcard.id + i}
                    title={adminhelpcard.title}
                    url={adminhelpcard.url}
                    thumbnail={adminhelpcard.thumbnail}
                  />
                ))}
              </InfiniteScroll>
            </div>
          ) : (
            <h1>Loading Cards</h1>
          )}
        </React.Fragment>
      </div>
    );
  }
}

我收到以下错误:

This expression is not callable.
  Type 'Boolean' has no call signatures.ts(2349)

从代码行中的“ deleteProduct”函数:

onClick={() => adminhelpcard.deleteProduct(this.state.id)}

[当我尝试单击帮助卡上的删除按钮时,它说没有识别出称为“ deleteProduct”的功能。我该如何解决这个问题?

javascript reactjs typescript
1个回答
0
投票

首先,您需要将deleteProduct函数作为prop传递给HelpCard组件。

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