#javascript #reactjs #ecmascript-6 #next.js
Вопрос:
Я пытаюсь отобразить список сообщений путем сопоставления с массивом. Я делал это много раз раньше, но по какой-то причине
renderPosts = async () => {
try {
let res = await axios.get('/posts');
let posts = res.data;
return posts.map((post, i) => {
return (
<li key={i} className="list-group-item">{post.text}</li>
);
});
} catch (err) {
console.log(err);
}
}
render () {
return (
<div>
<ul className="list-group list-group-flush">
{this.renderPosts()}
</ul>
</div>
);
}
Все, что я получаю, это:
Неперехваченная ошибка: Объекты недопустимы в качестве дочернего элемента React (найдено: [обещание объекта]). Если вы хотели отобразить коллекцию дочерних элементов, вместо этого используйте массив.
Я проверил данные, возвращенные с постов визуализации, и это массив с правильными значениями и без обещаний. Что здесь происходит?
Комментарии:
1. Вы можете вернуть только 1 объект из react. Вам нужно изменить return posts.map на const someVar = posts.map, а затем вернуть <ul>{someVar}<ul></ul> … таким образом, вы возвращаете завернутый объект. reactjs.org/docs/lists-and-keys.html
2. хотя первый комментарий верен, большая проблема заключается в том, что вы пытаетесь вернуть JSX из асинхронного метода, который не будет работать. вам нужно получить свои асинхронные данные
componentDidMount()
и позвонитьthis.setState
, когда ваш api вернется, вместо того, чтобы возвращать JSX напрямую3. Я пробовал это раньше с componentWillMount, потому что предполагал, что в этом проблема, но это не сработало. Просто сделал это с помощью componentDidMount, и это сработало! Спасибо, азиум.
Ответ №1:
this.renderPosts()
вернет Promise
не фактические данные, и AFAIK Reactjs не будет выполнять обещания неявно render
.
Тебе нужно сделать это вот так
componentDidMount() {
this.renderPosts();
}
renderPosts = async() => {
try {
const res = await axios.get('/posts');
const posts = res.data;
// this will re render the view with new data
this.setState({
Posts: posts
});
} catch (err) {
console.log(err);
}
}
render() {
const posts = this.state.Posts?.map((post, i) => (
<li key={i} className="list-group-item">{post.text}</li>
));
return (
<div>
<ul className="list-group list-group-flush">
{posts}
</ul>
</div>
);
}
Комментарии:
1. Это также помогло medium.com/front-end-hacking/…
Ответ №2:
Я также получил такое же сообщение об ошибке при создании асинхронного функционального компонента. Функциональные компоненты не должны быть асинхронными.
const HelloApp = async (props) => { //<<== removing async here fixed the issue
return (
<div>
<h2>Hello World</h2>
</div>
)
}
ReactDOM.render(<HelloApp />, document.querySelector("#app"))
Комментарии:
1. Это исправило это для меня — трассировка стека на самом деле не выдавала, что в этом была проблема!
2. Ни
render
одна функция в компонентах класса не может быть асинхронной, т. е. возвращать aPromise
.3. Точно. Вместо того, чтобы реализовывать асинхронность/ожидание непосредственно в функциональном компоненте, я добавил крючок useEffect внутри функционального компонента, как это
useEffect(async () => {//code with await keyword here}, [])
, и все работало нормально4. @EranG функция асинхронности’ должна быть внутри, как это useEffect( () => { асинхронная функция fetchData(){ //код с ключевым словом await здесь } fetchData ();}, []); Обратный вызов useEffect не может быть асинхронным.
Ответ №3:
Использование Крючков Реакции:
ОБНОВЛЕНИЕ 2020-08-01: Изменено по предложению @ajrussellaudio.
import React, {useState, useEffect} from "react"
const ShowPosts = () => {
const [posts, setPosts] = useState([]);
useEffect( () => {
async function fetchData() {
try {
const res = await axios.get('/posts');
setPosts(res.data);
} catch (err) {
console.log(err);
}
}
fetchData();
}, []);
return <div>{posts}</div>
}
Комментарии:
1. Обратный
useEffect
вызов не может бытьasync
, как указано в этой статье , на которую ссылаются в документах2. @ajrussellaudio, но он может сделать вот так… useEffect (() = > { асинхронная функция fetchData(){ попробуйте { const res = ожидание axios.get(‘/сообщения’); setPosts(res.данные); } поймать (ошибка) { console.log(ошибка); } } fetchData(); }, []);
Ответ №4:
Бедный я
Для всех, кто использует тест на шутку
И при попытке вызвать функцию дети затем получили эту ошибку
пожалуйста, проверьте:
const children = jest.fn().mockReturnValueOnce(null)
НЕ
const children = jest.fn().mockRejectedValue(null);
Ответ №5:
Если вы используете Next.js вы можете использовать это: Поместите свои коды в {}, если у вас есть какое-то соединение или какие-то вычисления, на которые требуется время, добавьте await
свои коды в {}.
import { useEffect } from 'react'
useEffect(async () => {.......},[])