Objects Are Not Valid as a React Child (Found: [Object Promise])

Objects are not valid as a React child (found: [object Promise])

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

ReactJS Error: Objects are not valid as a React child (found: [object Promise])

You can't render a default component from promise like that.

You can take a advantages of useState , useEffect hook to fetch and render data into the component.

You can learn more about React Hooks from this link.

And also your api response is a json object and you're trying to map over it.

Note: You can map over array type of data only.

Here is your working code of yours,

import { useEffect, useState } from "react";

const App = () => {
const [data, setData] = useState({});
useEffect(() => {
const getWeatherFromApiAsync = async () => {
const resopnse = await fetch(
"https://api.openweathermap.org/data/2.5/weather?q=brighton,uk&appid=8b609354454cdb6c5a7092a939861ace&units=metric"
);
const resopnseJson = await resopnse.json();
console.log("json", resopnseJson);
setData(resopnseJson);
};
getWeatherFromApiAsync();
}, []);

return (
<div className="App">
<h6>{data?.coord?.lon}</h6>
</div>
);
};

export default App;

Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead. ReactJS

Your index blog component should not be declared async. React function components are pure, synchronous functions.

const index = async (props) => { // <-- implicitly returns Promise object
console.log(props)
return (
<div>
<Head>
<title>BLOG TITLE</title>
<meta name="description" content="" />
<meta name="keywords" content="" />
<meta httpEquiv="Content-Type" content="text/html;charset=UTF-8" />
</Head>
<h1>BLOG HEADER</h1>
<BlogComponents />
</div>
);
};

export default index; // <-- implicitly returned Promise object

The component should a synchronous function.

const index = (props) => { 
useEffect(() => {
console.log(props);
}, [props]);

return (
<div>
<Head>
<title>BLOG TITLE</title>
<meta name="description" content="" />
<meta name="keywords" content="" />
<meta httpEquiv="Content-Type" content="text/html;charset=UTF-8" />
</Head>
<h1>BLOG HEADER</h1>
<BlogComponents />
</div>
);
};

objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children,

axios.get(...).then(...) returns a promise, which is what your info() function is returning. You need to find a way to get info() to return your desired JSX, not the promise.

Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead

In your productList component you are using a promise instead of rendering child, to overcome this you can make it a stateful component fix this like:

import React, { Component } from 'react';
import Product from "./Product/index";

class ProductList extends Component {
constructor(props) {
super(props)
this.state = {
goods: []
}
}

componentDidMount = () => {
import("../../../data/data.json")
.then(json => this.state({ goods: json.goods }))
}

render() {
const { goods } = this.state
return (
<div>
{goods.map(image => <div><Product images={image.pictures} /></div>)}
</div>
)
}
}

export default ProductList;

or alternatively you can import it in beginning like:

import React from 'react';
import Product from "./Product/index";
import goods from "../../../data/data.json"

const ProductList = () => {
const renderedGoods = goods.map(image => {
return <div><Product images={image.pictures} /></div>
})
return <div>{renderedGoods}</div>
}

export default ProductList;

Not an issue, yes you resolved the promise correct,

but as even when you type in console what you are actually returning is a promise and .then or .catch are callbacks called when its either resolved or rejected so you see react wants is something to render and you cannot render a promise

× Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead

Your problem is on TaskList component. I would suggest you to modify your code in this way:

import React, { useState, useEffect } from 'react'
import axios from 'axios'
import Task from './Task'

function TaskList() {
const [all_tasks, setAllTask] = useState();

async function getAllTasks(url){
let resp = await axios.get(url);
console.log('the type of resp in getAllTasks: ', typeof(resp));
let all_tasks= await resp.data
console.log('the type of resp in getAllTasks.data : ', typeof(all_tasks));
return all_tasks;
}

useEffect(() => {
(async () => {
let newTask = await getAllTasks('http://127.0.0.1:8000/api/read');
setAllTask(newTask);
console.log('all tasks rec-d from getAllTasks are', newTask);
console.log('& the type is: ', typeof(newTask));
})()
}, [])


return (
<div className="TaskList">
{
all_tasks.map(function(task){
console.log('the task i m going to give to Task compont. is: ',task);
return(
<div>
<p>the task title is {task.title}</p>
<Task task={task} />
</div>
)
})
}
</div>
)
}

export default TaskList;

Explanation:

  1. Removed async from component (you can't init an async component);
  2. If you need to render some, you need to init a state variable using useState hook;
  3. Move getAllTasks function inside component's body;
  4. Use an useEffect hook to fetch data from API (by doing this one time on component's mounting (bracket [] as useEffect's second parameter means this));


Related Topics



Leave a reply



Submit