对象作为 React 子级无效(发现:[object Promise])

Posted

技术标签:

【中文标题】对象作为 React 子级无效(发现:[object Promise])【英文标题】:Objects are not valid as a React child (found: [object Promise]) 【发布时间】:2018-05-19 10:01:49 【问题描述】:

我正在尝试通过数组映射来呈现帖子列表。我以前做过很多次,但出于某种原因

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 子项无效(找到:[object Promise])。如果您打算渲染一组子项,请改用数组。

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

【问题讨论】:

你只能从反应中返回 1 个对象。您需要将 return posts.map 更改为 const someVar = posts.map,然后返回 someVar ...这样,您将返回一个包装的对象。 reactjs.org/docs/lists-and-keys.html 虽然第一条评论是正确的,但更大的问题是你试图从一个不起作用的异步方法返回 JSX。您需要在componentDidMount() 中获取您的异步数据并在您的 api 返回而不是直接返回 JSX 时调用 this.setState 我以前用 componentWillMount 试过这个,因为我认为这是问题所在,但它没有用。只需使用 componentDidMount 就可以了!谢谢 azium。 【参考方案1】:

this.renderPosts() 将返回 Promise 而不是实际数据,AFAIK Reactjs 不会在 render 中隐式解析 Promise。

你需要这样做

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

【讨论】:

这也有帮助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"))

jsfiddle

【讨论】:

这为我解决了问题 - 堆栈跟踪并没有真正表明这是问题所在! 类组件中的render函数都不能是异步的,即返回Promise 没错。我没有直接在功能组件上实现 async/await,而是在功能组件中添加了 useEffect 钩子,就像这样 useEffect(async () =&gt; //code with await keyword here, []) 并且一切正常 @EranG async func' 应该在里面这样 useEffect( () => async function fetchData() //code with await keyword here fetchData(); , []); useEffect 回调不能是异步的。【参考方案3】:

可怜的我

对于任何使用开玩笑测试的人

并尝试调用函数 children 然后收到此错误

请检查:

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

不是

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

【讨论】:

【参考方案4】:

使用 React Hooks:

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>

【讨论】:

useEffect 回调不能是 async,正如在 the docs 中引用的 this article 中所指出的那样 @ajrusselaudio 但他可以这样做... useEffect( () => async function fetchData() try const res = await axios.get('/posts'); setPosts( res.data); catch (err) console.log(err); fetchData(); , []);【参考方案5】:

如果你使用 Next.js,你可以使用这个: 将您的代码放入 ,如果您有一些连接或一些计算需要时间,请将 await 添加到 中的代码中。

import  useEffect  from 'react'

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

【讨论】:

以上是关于对象作为 React 子级无效(发现:[object Promise])的主要内容,如果未能解决你的问题,请参考以下文章

React 错误:对象作为 React 子级无效,如果您打算渲染子级集合,请改用数组

“对象作为 React 子级无效。如果您要渲染一组子级,请改用数组。”错误

对象作为 React 子级无效如果您要渲染子级集合,请改用数组

错误:对象无效作为React子级(Axios和openweathermap API)

对象作为 React 子级无效。如果您打算渲染一组孩子,请改用数组 - FlatList

尝试基于 AsyncStorage React-Native 渲染组件时,对象作为反应子级无效