Я новичок в реакции, и я пытаюсь распечатать некоторые данные из запроса GET и распечатать их, но я получаю Uncaught TypeError: this.props.todos.map не является функцией - ошибкой.
Если я изменю this.setState({data: data}) на функцию успеха, я смогу получить данные в своей консоли, но есть ли какой-нибудь быстрый и простой способ исправить это, чтобы распечатать данные?
App.js
import React, { Component } from 'react';
import $ from 'jquery';
import Todos from "./Components/Todos"
class App extends Component {
constructor(){
super();
this.state = {
todos:[]
}
}
getTodos(){
$.ajax({
type: "GET",
url: 'url',
dataType:'json',
headers: {
Authorization: "Basic " + btoa("username" + ":" + "password")
},
cache: false,
success: function(data){
this.setState({todos: data}, function(){
console.info(this.state);
});
}.bind(this),
error: function(xhr, status, err){
console.info(err);
}
});
}
componentWillMount(){
this.getTodos();
}
componentDidMount(){
this.getTodos();
}
render() {
return (
<div className = "App">
<Todos todos = {this.state.todos}/>
</div>
);
}
}
export default App;
Todos.js
import React, { Component } from 'react';
import TodoItem from './TodoItem';
class Todos extends Component {
render() {
let todoItems;
if (this.props.todos){
todoItems = this.props.todos.map(todo => {
return (
<TodoItem key = {todo.code} todo = {todo} />
);
});
}
return (
<div className = "Todos">
<h3>Results:</h3>
{todoItems}
</div>
);
}
}
export default Todos;
TodoItem.js
import React, { Component } from 'react';
class TodoItem extends Component {
render() {
return (
<li className = "Todo">
<strong>{this.props.todo.code}</strong>
</li>
);
}
}
export default TodoItem;
Фрагмент из журнала консоли:
Можете ли вы console.info(this.state.todos) внутри App.js
@Andy this.props.todos инициализируется пустым массивом в компоненте оболочки. this.state = { todos:[] } нет необходимости в нулевой проверке
@ Энди, я сталкивался с этой проблемой много раз до такой степени, что могу заметить ее за много миль
что печатается в журнале консоли внутри обратного вызова успеха? вы уверены, что ваш сервер возвращает массив?
Очевидно, что сервер не возвращает массив, он должен возвращать объект, и поэтому .map не является ошибкой функции.
@Subin также может быть неопределенным, когда он пытается отобразить элемент, поэтому карта функций выдает ошибку, поскольку он пытается выполнить рендеринг до того, как состояние будет заполнено ответом
@AbdeslemCharif никогда не будет неопределенным, поскольку он правильно инициализирован в конструкторе компонентов приложения. Начальное состояние - это пустой массив. Первоначально он будет передаваться в пустом массиве, что не вызовет никаких проблем. Затем его сервер может вернуться и возразить, что он передает его, и второй рендеринг Todos выдает эту ошибку.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Во-первых, бесполезно вызывать this.getTodos() дважды, просто вызовите его в методе componentDidMount(), еще одна вещь, о которой вам нужно знать, компонент TodoItem.js не будет отображать значение this.props.todo.code, чтобы избежать проблемы, которую вам нужно добавить в свой TodoItem.js
class TodoItem extends Component {
render() {
if (!this.props.todo){
<div>Loading</div>
}
return (
<li className = "Todo">
<strong>{this.props.todo.code}</strong>
</li>
);
}
}
Array.prototype.map() ожидает массив, поэтому, если вы попытаетесь передать ему неопределенное значение, он автоматически выдаст ошибку, если я верю, что это так в вашем приложении
еще одна вещь, сделайте это с this.state.todo, прежде чем пробовать мое решение
Запрошенные данные находятся внутри {}, а не в массиве, поэтому я получаю сообщение об ошибке?
он также может быть undefined, так как вы пытаетесь выполнить рендеринг до получения ответа, также добавил этот this.getTodos = this.getTodos.bind(this) в свой конструктор
Вам также необходимо привязать функцию getTodos для ссылки на область класса внутри нее. Так что привяжите его внутри конструктора:
this.getTodos = this.getTodos.bind(this)
Это не имеет значения, поскольку this.getTodos вызывается из componentDidMount (), а не передается как onClick или onChange. Также к этому привязаны обратные вызовы внутри getTodos.
todos всегда должен быть массивом. Поэтому измените setState вот так в своей функции успеха.
this.setState({todos: (data.resources ? data.resources : [])}, function(){
console.info(this.state);
});
публиковать журнал консоли, который вы получаете, когда делаете console.info (this.state);