Попытка отобразить данные для реагирования

#javascript #reactjs #ajax #mern

#javascript #reactjs #ajax #mern

Вопрос:

Новое в React, попытка отобразить данные (внутри модального загрузчика) из MongoDB для реагирования с помощью запроса axios ajax. Postman показывает правильность. React выдает "TypeError: this.state.reviews.map is not a function" ошибку, которая говорит мне, что это не массив, поскольку .map() это метод массива, но я сохраняю состояние в виде массива. Очень смущен тем, как отображать данные в React, может кто-нибудь привести пример того, как это сделать правильно? Искал здесь, документы, Google, все еще не понимаю.

Результат Postman

 import React from 'react';
import Axios from 'axios';
import Rater from 'react-rater';
import './comment-styles.scss';

export class CommentBox extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            reviews: []
        }
        this.addReview = this.addReview.bind(this);
    };


    addReview() {
        Axios({
            method: 'POST',
            url: 'http://localhost:8080/breakfast-tacos/reviews',
            headers: {
                'Content-Type': 'application/json'
            }
        }).then(response => {
            this.setState({ reviews: [response.data.id] })      
        }).catch(error => console.log(error))
    }


    componentDidMount() {

        Axios.get('http://localhost:8080/breakfast-tacos/')
        .then(reviews => {
            this.setState({ reviews: reviews.data })
        })
        .catch(err => console.log(err))
    };



    render() {
        
        return (
            <div id="commentWrapper">
                <div className="commentHeader">
                    <h5>Leave a Rating!</h5>
                    <Rater style={{fontSize: '35px'}} />
                    <button id="submitRatingBtn" type="submit">Submit</button>

                    <form action="/breakfast-tacos" method="POST">
                        <textarea className="reviewTextBox" maxLength="250" placeholder="Write a review..." name="reviews"></textarea>
                        <button id="submitReviewBtn" type="submit" onClick={this.addReview}>Submit</button>
                    </form>

                </div>
                <hr />
                <div className="reviews">
                    <span className="user">
                        <h6>username:</h6>
                    </span>
                    <span className="text">
                        
                        {this.state.reviews.map((review, text) => {  
                                return (
                                    <p key={text}>
                                        {review} /*Where I want to display the data*/
                                    </p>
                                )
                            })}

                    </span>
                </div>
                <hr />
            </div>
        )
    }
};


 

Комментарии:

1. Что вы получите, если добавите console.log(reviews.data) раньше this.setState({ reviews: reviews.data }) ?

2. Кроме того, можете ли вы показать формат данных ответа addReview ?

3. @Ibra я добавил console.log(reviews.data.reviews) перед setState , и он правильно отображает данные в виде массива в консоли. Но когда я пытаюсь отобразить массив, он выдает эту ошибку: Error: Objects are not valid as a React child (found: object with keys {_id, reviews}). If you meant to render a collection of children, use an array instead. что очень сбивает с толку, потому что в консоли отображается массив.

4. @Ajeet Shah Я не уверен, что вы имеете в виду, я новичок в серверной части. Но когда я пытаюсь выполнить запрос post в postman, он говорит: `не удалось получить ответ` Error: socket hang up .

Ответ №1:

Данные ответа — это объект со свойством reviews , представляющим собой массив, поэтому вам нужно написать:

 componentDidMount() {

        Axios.get('http://localhost:8080/breakfast-tacos/')
        .then(reviews => {
            this.setState({ reviews: reviews.data.reviews })
        })
        .catch(err => console.log(err))
    };
 

И в части JSX:

{review.reviews}

потому review что это элемент массива, который является объектом.

Комментарии:

1. Я пробовал это, но все равно не повезло, я получаю эту ошибку : Warning: Each child in a list should have a unique "key" prop . Я изменил ключ на id , все та же ошибка. Также Check the render method of в поле комментариев указано `компонент`. Очень смущен, потому что консоль отображает данные правильно.

2. Это предупреждение, а не ошибка. Но хорошо бы предоставить уникальные ключи для повышения производительности. Итак, вы можете сделать: <p key={review._id}> {review.reviews} </p> .

3. Попробовал это, и все равно выдает то же предупреждение.

4. Можете ли вы создать изолированную среду для воспроизведения ваших проблем?

Ответ №2:

Вы все еще находитесь в массиве. Чтобы отобразить массив, вам необходимо найти свойства объекта.

 addReview() {
        Axios({
            method: 'POST',
            url: 'http://localhost:8080/breakfast-tacos/reviews',
            headers: {
                'Content-Type': 'application/json'
            }
        }).then(response => {
            this.setState({ reviews: [response.data.id] })      
        }).catch(error => console.log(error))
    }


    componentDidMount() {

        Axios.get('http://localhost:8080/breakfast-tacos/')
        .then(reviews => {
            this.setState({ reviews: reviews.data.reviews })
        })
        .catch(err => console.log(err))
    };
 

Теперь вы должны иметь возможность отображать массив, не видя ошибки.

Комментарии:

1. Я попробовал это, и я также поставил console.log(reviews.data.reviews) перед setState, и он отображает данные в консоли в виде массива, но когда я пытаюсь отобразить их в JSX, он выдает новую ошибку: Error: Objects are not valid as a React child (found: object with keys {_id, reviews}). If you meant to render a collection of children, use an array instead.