我有一个API,可为我提供具有以下属性的对象:id,title,url,thumbnailUrl。
我有一个模块负责该卡,该模块具有以下代码:
export interface Manual {
id?: string | number;
url: string;
title: string;
thumbnail?: string | null;
}
我有一个模块负责创建实际的HelpCard组件,其代码如下:
interface Props {
card: Manual;
deleteProduct: Function;
editProduct: Function;
type: "videos" | "manuals";
}
interface State {
editedCard: Manual;
imageLoading?: boolean;
tooManyRequests?: boolean;
}
export default class HelpCard extends Component<Props, State> {
state = {
editedCard: {
id: -1,
url: "",
title: "",
thumbnail: ""
},
imageLoading: true,
tooManyRequests: false
};
componentDidMount() {}
onEditClick = (card: Manual): void => {
this.setState({ editedCard: card });
};
updateEditCard = (event: React.FormEvent<HTMLInputElement>, key: "url" | "title" | "thumbnail"): void => {
const value = event.currentTarget.value;
this.setState((prevState: State) => {
return { editedCard: { ...prevState.editedCard, [key]: value } };
});
};
render() {
const { card } = this.props;
const { editedCard } = this.state;
return (
<React.Fragment>
<div className="card">
<div className="card-img">
{this.state.imageLoading ? <img src={placeholder} style={{ width: "100%", height: "100%" }}></img> : null}
<img
className="cardImage"
style={
this.state.tooManyRequests
? { display: "none" }
: this.state.imageLoading
? { display: "null" }
: { display: "block" }
}
onLoad={() => this.setState({ imageLoading: false })}
onError={() => this.setState({ tooManyRequests: true })}
src={card.thumbnail ? card.thumbnail : placeholder}
/>
</div>
<div className="card-body">
<div style={{ textAlign: "center" }}>
<span className="card-title">{card.title}</span>
<hr></hr>
</div>
<div className="card-buttons">
<div className="group">
<Modal
trigger={
<Button
onClick={() => this.onEditClick(card)}
style={{ width: "90px" }}
icon="mode_edit"
className="btn blue-outline"
href="#!">
Edit
</Button>
}>
<form
onSubmit={(e) => e.preventDefault()}
id="videoCardEdit"
style={{ width: "auto", height: "auto" }}>
<div>
<div>
<label>Title:</label>
<input
className="input"
style={{ width: "100%" }}
name="videoCardTitle"
onChange={(e: React.FormEvent<HTMLInputElement>) => this.updateEditCard(e, "title")}
value={editedCard.title}></input>
</div>
<div>
<label>URL:</label>
<input
className="input"
style={{ width: "100%" }}
name="videoCardURL"
onChange={(e: React.FormEvent<HTMLInputElement>) => this.updateEditCard(e, "url")}
value={editedCard.url}></input>
</div>
<div>
<label>Thumbnail URL:</label>
<input
className="input"
style={{ width: "100%" }}
name="videoCardThumbnail"
onChange={(e: React.FormEvent<HTMLInputElement>) => this.updateEditCard(e, "thumbnail")}
value={editedCard.thumbnail}></input>
</div>
<br></br>
</div>
<Button
type="submit"
className="btn green-outline"
icon="check"
length="fullwidth"
style={{
float: "left"
}}
onClick={() =>
this.props.editProduct(
card.id,
editedCard.title,
editedCard.url,
editedCard.thumbnail,
this.props.type
)
}>
confirm
</Button>
<br></br>
</form>
</Modal>
<Button
icon="delete"
style={{ width: "90px" }}
onClick={() => this.props.deleteProduct(card.id, this.props.type)}
className="btn red-outline">
Delete
</Button>
</div>
</div>
</div>
</div>
</React.Fragment>
);
}
}
然后,使用以下代码将该卡显示在HelpList组件上:
export default class HelpList extends Component<Props, State> {
state = {};
async componentDidMount() {}
render() {
console.log(this.props.data);
return (
<div className="row">
{this.props.data.map((card: Manual) => (
<HelpCard
card={card}
key={card.id}
deleteProduct={this.props.onDelete}
editProduct={this.props.onEdit}
type={this.props.type}
/>
))}
</div>
);
}
}
在HelpAdmin.view.tsx模块上显示的最终列表,该模块加载我的卡,并具有所有API功能,例如我的创建/删除/编辑调用。
状态和加载功能如下:
export class HelpAdminView extends Component<Props, State> {
state = {
title: "",
thumbnail: "",
url: "",
error: null,
isEditProduct: true,
isAddProduct: true,
whichRadioSelected: "video",
videos: [],
manuals: []
};
componentDidMount() {
this.loadAdminHelpCard("videos");
this.loadAdminHelpCard("manuals");
}
loadAdminHelpCard = (type: "videos" | "manuals"): void => {
const url = `${BASE_API_URL}/${type}`;
axios
.get(url)
.then((res) => {
this.setState({ [type]: res.data } as any);
})
.catch(function(error) {
// handle error
console.log(error);
});
};
最后,我的编辑功能如下:
editProduct = (id: any, title: string, url: string, thumbnail: string, type: "videos" | "manuals") => {
const apiUrl = `${BASE_API_URL}/${type}/${id}`;
axios
.put(apiUrl, {
title: title,
url: url,
thumbnail: thumbnail
})
.then((response: any) => {
// ? UPDATE the list with new card information here
})
.catch(function(error) {
console.log(error);
});
};
当用户单击“编辑”时,会将卡片从道具中复制并进入一种状态。现在仅编辑卡的状态。 (this.state.editedCard)当用户单击提交时,editedCard的详细信息将提供给editProduct(id,标题,缩略图等)。 在HelpAdmin.view.tsx中,正在进行API调用,该调用将使用新卡的详细信息更改数据库。
我要弄清楚的是如何在视频/手册中更新我们的卡,以使其反映在用户界面中。 (启用成功的API调用)
在此先感谢您的阅读和帮助!
答案 0 :(得分:1)
当更新操作结束时,您可以获得当前数据。
.then((response: any) => {
//here get the recent data from your api
// ? UPDATE the list with new card information here
this.loadAdminHelpCard("videos");
this.loadAdminHelpCard("manuals");
})
因此,这将更新状态,从而导致父组件重新呈现,这也将重新呈现子组件,因此您的Card组件将获取新数据。
所有editProduct函数:
editProduct = (id: any, title: string, url: string, thumbnail: string, type: "videos" | "manuals") => {
const apiUrl = `${BASE_API_URL}/${type}/${id}`;
axios
.put(apiUrl, {
title: title,
url: url,
thumbnail: thumbnail
})
.then((response: any) => {
//here get the recent data from your api
// ? UPDATE the list with new card information here
this.loadAdminHelpCard("videos");
this.loadAdminHelpCard("manuals");
})
.catch(function(error) {
console.log(error);
});
};