【问题标题】:Objects are not valid as a React child when trying to map尝试映射时,对象作为 React 子项无效
【发布时间】:2020-04-04 19:52:03
【问题描述】:

我正在尝试从我的 api 获取数据并将其呈现为列表,但它不断给我标题中提到的错误。

import React, { Component } from "react";
import "./style/list.css";
import { getEvents } from "../services/eventService";
import { thisExpression } from "@babel/types";

class Likes extends Component {
  constructor(props) {
    super(props);
    this.state = {
      events: []
    };
  }
  async componentWillMount() {
    const { data: events } = await getEvents();
    this.setState({ events });
    console.log(events);
  }

  async getUserLikes() {
    // Get Likes TODO
    return 1;
  }

  render() {
    return (
      <div>
        <ul class="list-group">
          {this.state.events.map(event => (
            <li
              class="list-group-item d-flex justify-content-between align-items-center"
              key={event._id}
            >
              {event.title}
              <span class="badge badge-primary badge-pill">
                {this.getUserLikes()}
              </span>
            </li>
          ))}
        </ul>
      </div>
    );
  }
}

export default Likes;

虽然很奇怪,似乎当我从渲染中删除 getUserLikes() 函数时,映射工作,但当我添加它时,它没有。

【问题讨论】:

  • 这是getUserLikes的真实代码吗?或者你正在执行它的请求?
  • 起初是一个请求,但我删除了它以查看问题出在哪里。即使使用像这样的 getUserLikes 它也不起作用,但一旦删除它就会起作用
  • 如果您删除 async 标志并返回 1 它将起作用。但对于您的实际用例,它不会
  • 您是否偶然检查过official tutorials 的主题?

标签: javascript reactjs


【解决方案1】:

问题是getUserLikesasync

当以async 调用函数时,它将返回一个 Promise 对象,该对象不是可渲染的。

如果你想调用render里面的某个函数,它不能是async

即使getUserLikes没有调用异步请求,如果你在它前面加上async,它也会返回一个promise对象。

您可以在下面的示例中看到这种行为。

async function call1() { return 1; }

function call2() { return 1; }

// Promise Object
console.log(call1())
// Actual returned value
console.log(call2())

如果你想获取数据并渲染它,你应该在componentDidMount中获取它,而不是在渲染内部。

【讨论】:

    【解决方案2】:

    问题在于您的处理程序的async 特性。组件的返回语句必须是纯的。您不能在 jsx 块内声明命令式代码。

    通常在这种情况下,您希望声明一个本地状态,该状态最终会被返回的数据填充并在此之前充当占位符。

    const Component = () =>{
        const [data, setData] = useState(null)
    
        useEffect(() =>{
            fetch(/*..*/).then(response => setData(response))
        },[])
    
        return data ? data.map(/*...*/) : <div> Loading </div>
    }
    

    【讨论】:

      猜你喜欢
      • 2021-06-03
      • 2021-03-21
      • 2022-01-10
      • 2022-01-13
      • 2018-06-02
      • 1970-01-01
      • 1970-01-01
      • 2021-04-06
      • 1970-01-01
      相关资源
      最近更新 更多