how to delete a single item using axios in react

前端 未结 2 2001
别那么骄傲
别那么骄傲 2021-01-28 20:28

I have looked into many articles and posts like this but it does not work in my case.I simply need to delete an item from my post list in my application using axios. In the axio

相关标签:
2条回答
  • 2021-01-28 20:43

    Thanks @FranklinFarahani. I had to write an answer as it is too long. I have changed my get and post method and managed to fix the delete method. I use the unique key that firebase is creating per post to delete each item. I get that inget method. This is the entire code.

     // 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>
            );
        }
    }
    

    The problem is my state is not updated after delete so although the post has been deleted from my database it is still in the DOM.

    And more importantly if submit a new post cannot delete it after a get request or refresh being done. The reason is in post request the key will be created after the request is done and therefor I will not have the key to update state and DOM until after the next get request or refresh. And the id will be the temporary one which I assign during post method which cannot be used to delete a post.

    0 讨论(0)
  • 2021-01-28 20:54

    You are not specifying what your Post component should delete. In other words, the props.delete is not receiving an id to pass up to your parent component. In order to do that, you can change that to () => props.delete(props.id) and then in your parent component you need to have the handleDelete method receive the id of the item you want to target which is the id we passed up earlier from Post.

    I don't know how your server is set up but using the axios request you originally have in your question your code would look like this:

    handleDelete = (itemId) => {
        // Whatever you want to do with that item
        axios.delete("url", { params: { id: itemId } }).then(response => {
          console.log(response);
        });
    

    Here's a CodeSandbox (using some dummy data in the constructor) displaying the item being passed in a console.log() (axios statement is commented out).


    EDIT: How to make axios delete requests using Firebase REST API

    Oh sorry, I did not see that you were using Firebase. Direct REST requests are a bit different with Firebase. In your configuration the requests should look like this:

    axios.delete(`${url}/${firebasePostId}.json`).then(response => {
        console.log(response)
    })
    

    This is assuming your Firebase rules allow unauthorized requests (which I strongly advise against, seeing as anyone could send this request).

    Please note that firebasePostId is the push key provided by Firebase when you send POST requests to them, and are in fact a great choice of id for your posts. An example of one is -LOLok8zH3B8RonrWdZs which you mentioned in the comments.

    For more information on Firebase REST API syntax, check out their documentation.

    0 讨论(0)
提交回复
热议问题