将创建方法与 HTTPS 发布请求 [ReactJs] 一起使用时出错



所以我最近一直在为一个显示卡片列表的页面开发一个管理控制面板(一些视频和一些基于文本的(。我正在托管一个本地 API,它生成 7 个不同的独特数据帖子(这些帖子包括帖子的 ID、标题、网址、缩略图(。我设法创建了 2 种单独的方法,一种是删除卡,另一种是编辑卡按钮。我现在正在尝试添加一个"创建"按钮,该按钮打开一个带有空字段的模式弹出窗口,允许管理员用户插入它,单击创建后,一个新的数据字段将添加到 API 的数据库中。

下面的代码用于创建的 HelpList.tsx(负责显示卡片列表(模块,该模块包含 deleteProduct、editProduct 和 createProduct 方法。我试图将我的createProduct函数基于editProduct函数,尽管我不确定该函数是否知道如何为卡片/帖子提供递增且适当的ID。

import React, { Component } from "react";
import HelpCard from "./HelpCard";
import "../help/HelpCard.css";
import axios from "axios";
import InfiniteScroll from "react-infinite-scroller";
import Popup from "reactjs-popup";
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 {
//createProduct: (title: string, url: string, thumbnail: string) => void;
}
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: {}
//isEditProduct: true,
//isAddProduct: true
};
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, title: string, url: string, thumbnail: string) {
const { adminhelpcard } = this.state;
const apiUrl = `http://localhost:3000/videos/${id}`;
const options = {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
title,
url,
thumbnail
})
};
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 });
}
);
}
createProduct(title: string, url: string, thumbnail: string) {
const apiUrl = `http://localhost:3000/videos/`;
const options = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
title,
url,
thumbnail
})
};
fetch(apiUrl, options)
.then((res) => res.json())
.then(
(result) => {
this.setState({
response: result
});
},
(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
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 中可用的按钮中调用 editProduct 和 deleteProduct 函数,该按钮负责生成卡本身的结构。

下面的代码适用于视频卡,该视频卡还包含包含编辑产品字段和函数的组件(模式工具提示(:

<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="left center">
<form
onSubmit={(e) => e.preventDefault()}
id="videoCardEdit"
style={{ width: "auto", height: "auto" }}>
<div>
<div>
<label>Title:</label>
<input
name="videoCardTitle"
onChange={(e) => {
this.setState({ title: e.target.value });
}}
value={this.state.title}></input>
</div>
<div>
<label>URL:</label>
<input
name="videoCardURL"
onChange={(e) => {
this.setState({ url: e.target.value });
}}
value={this.state.url}></input>
</div>
<div>
<label>Thumbnail URL:</label>
<input
name="videoCardThumbnail"
onChange={(e) => {
this.setState({ thumbnail: e.target.value });
}}
value={this.state.thumbnail}></input>
</div>
</div>
<button
className="btnConfirm"
style={{
float: "left"
}}
onClick={() =>
this.props.editProduct(
this.props.id,
this.state.title,
this.state.url,
this.state.thumbnail
)
}
id="confirmModalBtn">
confirm
</button>
</form>
</Popup>
<button onClick={() => this.props.deleteProduct(this.props.id)} className="btn">
Delete
</button>
</div>
</div>
</div>
</div>
</div>

最后,我在我的HelpAdmin.view.tsx页面中插入"创建"按钮(这或多或少是我用于此任务的index.tsx/app.tsx,因为我在此面板页面中显示我的列表和按钮(。我正在尝试实现"创建"按钮,以便它显示在创建的组件的顶部。以下页面的代码如下所示:

import React, { Component } from "react";
import HelpList from "../components/helpAdmin/help/HelpList";
import "../components/helpAdmin/help/HelpList";
import Popup from "reactjs-popup";

interface Props {
createProduct: (title: string, url: string, thumbnail: string) => void;
}
interface State {
title: string;
thumbnail: string;
id: string;
url: string;
}
export class HelpAdminView extends Component<Props, State> {
componentDidMount() {}
render() {
return (
<main>
<div className="box">
<Popup trigger={<button className="btn"> Create a new card</button>} position="right center">
<div>
<div>
<label>Title:</label>
<input
name="createCardTitle"
onChange={(e) => {
this.setState({ title: e.target.value });
}}
value={this.state.title}></input>
</div>
<div>
<label>URL:</label>
<input
name="createCardURL"
onChange={(e) => {
this.setState({ url: e.target.value });
}}
value={this.state.url}></input>
</div>
<div>
<label>Thumbnail URL:</label>
<input
name="createCardThumbnail"
onChange={(e) => {
this.setState({ thumbnail: e.target.value });
}}
value={this.state.thumbnail}></input>
</div>
<button
style={{
float: "left"
}}
onClick={() => this.props.createProduct(this.state.title, this.state.url, this.state.thumbnail)}
className="btnCreate"
id="confirmModalBtn">
Create
</button>
</div>
</Popup>
<HelpList />
</div>
</main>
);
}
}
export default HelpAdminView;

这段代码在尝试运行项目时似乎不断向我抛出以下错误,如下所示:

Type error: Property 'createProduct' is missing in type '{}' but required in type 'Readonly<Props>'.  TS2741

我不确定为什么会抛出此错误,即使我尝试以与调用以前工作函数相同的方式调用此函数。我在这里明显错过了什么吗?

提前感谢您的任何帮助!

------------------------------编辑---------------------------------

以下代码是 HelpCard 中可用的界面属性.Tsx 然后调用函数,如上面的 onClick 代码所示。

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

HelpAdminView组件需要createProduct作为其props,因为它是必需的道具。在调用相同的<HelpAdminView />时,没有传递 prop,这就是抛出此类型错误的原因。 我们不能通过包含该组件来访问另一个组件的方法。在这种情况下,您将包含HelpList并尝试访问其中定义的方法。

最新更新