Я просмотрел много статей и сообщений, например this, но в моем случае это не работает . Мне просто нужно удалить элемент из моего списка сообщений в моем приложении, используя axios. В документах axios говорится, что вам нужно передать параметры методу удаления. Также у меня есть отправка в большинстве приложений, которые используют идентификаторы, не имея идентификаторов в своем состоянии. Но я не могу заставить его работать. Пожалуйста, посмотрите мой код целиком. Я знаю, что мой метод удаления неправильный, пожалуйста, помогите мне исправить это:

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

Я также вижу эту ошибку в консоли: Uncaught (в обещании) TypeError: невозможно преобразовать undefined или null в объект в Function.values, который находится в методе get. Еще раз спасибо.

0
azad6026 8 Окт 2018 в 03:18

2 ответа

Лучший ответ

Вы не указываете, что должен удалить ваш компонент Post. Другими словами, props.delete не получает id для передачи вашему родительскому компоненту. Для этого вы можете изменить его на () => props.delete(props.id), а затем в родительском компоненте вам нужно, чтобы метод handleDelete получал id элемента, на который вы хотите настроить таргетинг, который является id мы ушли ранее из Post.

Я не знаю, как настроен ваш сервер, но с использованием запроса axios, который у вас изначально есть в вашем вопросе, ваш код будет выглядеть так:

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

Вот CodeSandbox (с использованием фиктивных данных в конструкторе), отображающий передаваемый элемент в {{X0} } (утверждение axios закомментировано).


РЕДАКТИРОВАТЬ: как делать запросы на удаление axios с помощью Firebase REST API

Извините, я не видел, что вы используете Firebase. Прямые запросы REST немного отличаются от Firebase. В вашей конфигурации запросы должны выглядеть так:

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

Предполагается, что ваши правила Firebase разрешают неавторизованные запросы (чего я настоятельно не рекомендую, поскольку любой может отправить этот запрос).

Обратите внимание, что firebasePostId - это кнопка push, предоставляемая Firebase, когда вы отправляете им запросы POST, и на самом деле это отличный выбор id для ваших сообщений. Примером одного из них является -LOLok8zH3B8RonrWdZs, который вы упомянули в комментариях.

Для получения дополнительной информации о синтаксисе Firebase REST API ознакомьтесь с их документацией.

6
Franklin Farahani 9 Окт 2018 в 04:37

Спасибо @FranklinFarahani. Мне пришлось написать ответ, так как он слишком длинный. Я изменил методы получения и публикации, и мне удалось исправить метод удаления. Я использую уникальный ключ, который 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.

И что еще более важно, если отправить новое сообщение нельзя удалить его после выполнения запроса на получение или обновления. Причина в том, что в почтовом запросе ключ будет создан после того, как запрос будет выполнен, и поэтому у меня не будет ключа для обновления состояния и DOM до следующего запроса получения или обновления . И идентификатор будет временным, который я назначаю во время метода публикации, который нельзя использовать для удаления сообщения.

0
Samuel Liew 11 Окт 2018 в 00:31