对象作为 React 子对象是无效的(已找到: [对象承诺])

我试图通过一个数组映射来呈现一个文章列表。我以前做过很多次,但是因为某些原因

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 子对象无效(found: [ objectPromisy ])。如果要呈现子集合,则使用数组代替。

我已经检查了从 renderPosts 返回的数据,它是一个具有正确值的数组,没有承诺。这是怎么回事?

161555 次浏览

this.renderPosts() will return a Promise not the actual data, and AFAIK Reactjs will not resolve Promises implicitly in render.

You need to do it like this

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>
);
}

I also received the same error message when creating an async functional component. Functional components should not be async.

const HelloApp = async (props) =>  { //<<== removing async here fixed the issue
return (
<div>
<h2>Hello World</h2>
</div>
)
}
ReactDOM.render(<HelloApp />, document.querySelector("#app"))

jsfiddle

Poor me

For anyone using jest test

And trying to call a function children then received this Error

please check:

const children = jest.fn().mockReturnValueOnce(null)

NOT

const children = jest.fn().mockRejectedValue(null);

Using React Hooks:

UPDATE 2020-08-01: Amended with @ajrussellaudio's suggestion.

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>
}

If you use Next.js you can use this: Put your codes in {}, if you have some connection or some calculations thats need time, add await to your codes in {}.

import { useEffect } from 'react'


useEffect(async () => {.......},[])