#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, все еще не понимаю.
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.