I have a mapping and in each mapping i want to get data in the file storage IPFS such as the name. Then I want to return the name on the interface. However, I get a "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." Can someone please help me? been trying to solve this for hours. Can't seem to understand why because I know that hName should be a string.
{this.props.hawkers.map((hawker, key) => {
const hawkerDetails = axios
.get("https://ipfs.infura.io/ipfs/" + hawker.profileHash)
.then(function (response) {
console.log("this is the data: ", response.data);
return response.data;
})
.catch(function (error) {
console.log(error);
});
const hName = hawkerDetails.then((details) => {
return hName;
});
return (
<>
<h4 style={{ display: "flex", marginTop: 20 }}>
<Link
to={`/hawkerInfo/${hawker.owner}`}
// state={{ chosenHawkerPk: hawker.owner }}
state={{ chosenHawkerPk: hawker }}
>
{hName}
</Link>
</h4>
There are several things going on.
You're not using React state to manage your data.
You're passing in details
as an argument to your then
method, and then not using it so hName
is meaningless. It should probably be details.hName
.
Ideally you want to create an array of promises and then process the data with Promise.all
. In my example I've used async/await
.
Once you've set your state you then need to map
over your data in your return
to create the HTML.
// Initialise state
const [ hawkers, setHawkers ] = useState([]);
// Async function called by the `useEffect` method
async function getData() {
// Create a list of Axios promises
const promises = this.props.hawkers.map(hawker => {
const url = `https://ipfs.infura.io/ipfs/${hawker.profileHash}`;
return axios.get(url);
});
// Wait for all the data to return
const responses = await Promise.all(promises);
// Use `map` to return a new array of each response's data
const hawkers = data.map(response => response.data);
// Set the state with that array
setNames(hawkers);
}
// useEffect runs once if you pass in an empty
// array dependency
useEffect(() {
getData();
}, []);
if (!hawkers.length) return <div>Loading</div>;
// Now just `map` over the data that you put in state
return (
<>
{hawkers.map(hawker => {
<h4>
<Link to={`/hawkerInfo/${hawker.details.owner}`}>
{hawker.details.name}
</Link>
</h4>
})};
</>
)