如何在 React 中使用 axios 删除单个项目
我查看了许多文章和帖子,例如 这个 ,但它对我的情况不起作用。我只需要使用 axios 从我的应用程序的帖子列表中删除一个项目。在 axios 文档中,它说您需要将参数传递给删除方法。此外,我发现在大多数应用程序中,它们使用 id,而其状态中没有 id。但我无法让它工作。请查看我的整个代码。我知道我的删除方法是错误的,请帮我修复它:
// The individual post component
const Post = props => (
<article className="post">
<h2 className="post-title">{props.title}</h2>
<hr />
<p className="post-content">{props.content}</p>
<button onClick={props.delete}>Delete this post</button>
</article>
);
// The seperate form component to be written later
class Form extends React.Component {}
// The posts loop component
class Posts extends React.Component {
state = {
posts: [],
post: {
title: "",
content: ""
}
// error:false
};
componentDidMount() {
const { posts } = this.state;
axios
.get("url")
.then(response => {
const data = Object.values(response.data);
this.setState({ posts : data });
});
}
handleChange = event => {
const [name , value] = [event.target.name, event.target.value];
// const value = event.target.value;
const { post } = this.state;
const newPost = {
...post,
[name]: value
};
this.setState({ post: newPost });
};
handleSubmit = event => {
event.preventDefault();
const {post} = this.state;
const {posts} = this.state;
axios
.post("url", post)
.then(response => {
// console.log(response);
const newPost = Object.values(response.data);
this.setState({ post: newPost });
const updatedPosts = [...posts, {title:post.title,content:post.content}];
this.setState({ posts: updatedPosts});
// console.log(post);
console.log(updatedPosts);
console.log(this.state.posts);
});
};
handleDelete = () => {
const { post } = this.state;
axios.delete("url",{params: {id: post.id}})
.then(response => {
console.log(response);
});
};
render() {
let posts = <p>No posts yet</p>;
if (this.state.posts !== null) {
posts = this.state.posts.map(post => {
return <Post
key={post.id}
{...post}
delete={this.handleDelete}/>;
});
}
return (
<React.Fragment>
{posts}
<form className="new-post-form" onSubmit={this.handleSubmit}>
<label>
Post title
<input
className="title-input"
type="text"
name="title"
onChange={this.handleChange}
/>
</label>
<label>
Post content
<input
className="content-input"
type="text"
name="content"
onChange={this.handleChange}
/>
</label>
<input className="submit-button" type="submit" value="submit" />
</form>
</React.Fragment>
);
}
}
我还在控制台中看到此错误: 未捕获(在承诺中)TypeError:无法将未定义或 null 转换为对象 在 Function.values 中,它在 get 方法中。 再次感谢。
您没有指定
Post
组件应删除的内容。换句话说,
props.delete
没有收到
id
以传递给您的父组件。为了做到这一点,您可以将其更改为
() =>; props.delete(props.id)
,然后在您的父组件中,您需要让
handleDelete
方法接收您想要定位的项目的
id
,也就是我们之前从
Post
传递过来的
id
。
我不知道您的服务器是如何设置的,但使用您问题中最初提出的 axios 请求,您的代码将如下所示:
handleDelete = (itemId) => {
// Whatever you want to do with that item
axios.delete("url", { params: { id: itemId } }).then(response => {
console.log(response);
});
这是一个
CodeSandbox
(在构造函数中使用一些虚拟数据)显示传入
console.log()
的项目(axios 语句被注释掉)。
编辑:如何使用 Firebase REST API 发出 axios 删除请求
哦,抱歉,我没有看到您正在使用 Firebase。直接 REST 请求与 Firebase 略有不同。在您的配置中,请求应如下所示:
axios.delete(`${url}/${firebasePostId}.json`).then(response => {
console.log(response)
})
这是假设您的 Firebase 规则允许未经授权的请求(我强烈建议不要这样做,因为任何人都可以发送此请求)。
请注意,
firebasePostId
是您向 Firebase 发送
POST
请求时提供的推送密钥,实际上是您的帖子的
id
的绝佳选择。其中一个例子是您在评论中提到的
-LOLok8zH3B8RonrWdZs
。
有关 Firebase REST API 语法的更多信息,请查看其 文档 。
感谢@FranklinFarahani。我不得不写一个答案,因为它太长了。我已经更改了我的 get 和 post 方法,并设法修复了 delete 方法。我使用 firebase 为每个帖子创建的唯一键来删除每个项目。我得到了那个 inget 方法。这是整个代码。
// The individual post component
const Post = props => (
// use the key as an id here
<article id={props.id} className="post">
<h2 className="post-title">{props.title}</h2>
<hr />
<p className="post-content">{props.content}</p>
<button onClick={props.delete}>Delete this post</button>
</article>
);
// The Post lists component
class Posts extends React.Component {
state = {
posts: [],
post: {
id: "",
title: "",
content: ""
},
indexes: []
};
componentDidMount() {
const { posts } = this.state;
axios
.get("firebaseURL/posts.json")
.then(response => {
// create an array to hold th unique id as key and post as value using Object.entries
const retrievedPosts = [];
for (const [key, value] of Object.entries(response.data)) {
const post = {
id: key,
title: value.title,
content: value.content
};
// add allposts to the array here
retrievedPosts.push(post);
}
// update state
this.setState({ posts: retrievedPosts });
console.log(retrievedPosts);
});
}
handleChange = event => {
const [name, value] = [event.target.name, event.target.value];
// const value = event.target.value;
const { post } = this.state;
const newPost = {
...post,
[name]: value
};
this.setState({ post: newPost });
};
handleSubmit = event => {
event.preventDefault();
const { posts } = this.state;
// use this as a temporary id for post method
const postIndex = posts.length + 1;
const post = {
id: postIndex,
title: this.state.post.title,
content: this.state.post.content
};
axios
.post("firebaseURL/posts.json", post)
.then(response => {
const updatedPosts = [
...posts,
{ id: post.id, title: post.title, content: post.content }
];
// update state
this.setState({ posts: updatedPosts });
console.log(posts);
});
};
handleDelete = postId => {
event.preventDefault();
// get a copy of the posts
const posts = [...this.state.posts];
// in delete method use postId to create a unique url for the post to be deleted
axios
.delete(
"firebaseURL/posts/" + postId + ".json"
)
.then(response => {
//update state
this.setState({ posts: posts });
});
};
render() {
let posts = <p>No posts yet</p>;
if (this.state.posts !== null) {
posts = this.state.posts.map(post => {
return (
<Post
id={post.id}
key={post.id}
{...post}
delete={() => this.handleDelete(post.id)}
/>
);
});
}
return (
<React.Fragment>
{posts}
<form className="new-post-form" onSubmit={this.handleSubmit}>
<label>
Post title
<input
className="title-input"
type="text"
name="title"
onChange={this.handleChange}
/>
</label>
<label>
Post content
<textarea
className="content-input"
rows="7"
type="text"
name="content"
onChange={this.handleChange}
/>
</label>
<input className="submit-button" type="submit" value="submit" />
</form>
</React.Fragment>
);
}
}
问题是 我的状态在删除后没有更新 ,因此虽然帖子已从我的数据库中删除,但它仍然在 DOM 中。
更重要的是,如果提交新帖子,则在完成 get 请求或刷新后无法删除它。原因是在 post 请求中,密钥将在请求完成后创建,因此 在下一次 get 请求或刷新之前,我将没有更新状态和 DOM 的密钥 。并且 id 将是我在 post 方法期间分配的临时 id,不能用于删除帖子。