Я не могу перебирать элементы, которые я ввел в состояние из фиктивной конечной точки получения API:
Это весь мой компонент:
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
class TaskList extends Component {
constructor() {
super();
this.state = {
tasks: [], // I set the empty state for now
}
}
componentDidMount() {
fetch('/api/tasks') // I fetch the data
.then(response =>{
return response.json();
})
.then(tasks=>{
this.setState({tasks}); // I put the data into the state
});
}
renderTasks() {
return this.state.tasks.map(task => { // Here I want to iterate over the state and it fails
return (
<li>{task.title}</li>
);
})
}
render() {
return(
<ul>
{this.renderTasks()}
</ul>
);
}
}
export default TaskList;
if (document.getElementById('app')) {
ReactDOM.render(<TaskList/>, document.getElementById('app'));
}
Функция map
не видит данных. Почему?
app.js:57174 Uncaught TypeError: this.state.tasks.map is not a function
Я могу записать журнал console.info(this.state)
в renderTasks()
, и я получаю:
Вот ваш ответ, вы не можете использовать map () для объекта
Я добавляю данные для работы с массивом return this.state.tasks.data.map(task => {
, но это тоже не работает. Я слепой? Я что-то упускаю ...
Да, вы должны пытаться составить карту, только если задачи не пусты. ;) Теперь он сломается в первый раз, потому что ключ данных не существует в пустом массиве задач
Я отредактировал свой ответ, поэтому теперь, если данные не определены, он будет отображать пустой массив в первый раз :)
Вы пытаетесь отобразить объект, содержащий массив данных. Вы должны отобразить массив данных внутри объекта задач :)
renderTasks() {
const {tasks: {data}} = this.state;
return ([] || data).map(task => { // Here I want to iterate over the state and it fails
return (
<li>{task.title}</li>
);
})
}
Функция карты может применяться только к массиву, а не к объекту, как показано на изображении tasks
- это объект, а tasks.data
- это массив. Вы должны установить состояние следующим образом:
.then(tasks=>{
this.setState({tasks: tasks.data}); // putt array rather than object
});
Этого также можно добиться (если не применять вышеуказанное решение):
this.state.tasks.data.map();
Это помогло. Я должен установить состояние из tasks.data
. Тогда я могу составить карту через return this.state.tasks.map(task =>
. Проклятые JS-фреймворки! Ненавижу их. Спасибо Умайр.
Попробуйте следующее:
renderTasks() {
if (this.state.tasks.hasOwnProperty('data')) {
return this.state.tasks.data.map(task => { // Here I want to iterate over the state and it fails
return (
<li>{task.title}</li>
);
})
} else {
return (null);
}
}
когда компонент выполняет рендеринг в первый раз, использование this.state.tasks.data.map
завершится ошибкой, потому что данные не являются ключевыми в this.state.tasks
, поскольку выборка запускается только после DidMount()
.
Это означает, что если this.state.tasks имеет ключ данных, затем сопоставить эти данные, иначе вернет значение null.
Вы забыли разобрать свой JSON? Мне кажется, он пытается отобразить строку?