Reputation: 3
I’ve tried to just add another fetch
to see if it would work but it hasn't. can anyone explain this issue so i get something out of this.
<ul className="">
{ async function fetchURL() {
const res = await axios.get(ability.ability.url);
const data = res.data;
setabilityDes(data)
pokedata.abilities.map( async (ability, index) => (
<li key={index} className="inline px-3" > {ability.ability.name}
<p>{data.effect}</p>
</li>
))}}
</ul>
This is the error i am getting:
'Warning: Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it. ul div div div div PokemonData@http://localhost:5173/src/pages/PokemonData.jsx?t=1711809411667:23:20 RenderedRoute@http://localhost:5173/node_modules/.vite/deps/react-router-dom.js?v=45fa90fa:3563:7 Routes@http://localhost:5173/node_modules/.vite/deps/react-router-dom.js?v=45fa90fa:3997:7 Router@http://localhost:5173/node_modules/.vite/deps/react-router-dom.js?v=45fa90fa:3945:7 BrowserRouter@http://localhost:5173/node_modules/.vite/deps/react-router-dom.js?v=45fa90fa:4682:7 App'
I’ve also tried make a new component for just the ability section but i kept running into errors so i thought this would be more efficient
Upvotes: 0
Views: 535
Reputation: 57
You don't use functions and logic codes in jsx section!
change your code to this:
import { useState, useEffect } from "react";
import axios from "axios";
const Component = () => {
const [abilities, setAbilities] = useState([]);
async function fetchURL() {
const res = await axios.get("url to fetch");
const data = res.data;
setAbilities(data);
}
useEffect(() => {
fetchURL();
}, []);
return (
<ul className="">
{abilities.map((ability, index) => (
<li key={index} className="inline px-3">
{ability.name}
<p>{ability.effect}</p>
</li>
))}
</ul>
);
};
export default Component;
for learn more about this codes go to react documents
if you need a map in array for fetch all urls, you can use this code instead up code:
import { useState, useEffect } from "react";
import axios from "axios";
const urls = [
{
id: 1,
url: "https://jsonplaceholder.typicode.com/posts",
},
{
id: 2,
url: "https://jsonplaceholder.typicode.com/posts",
},
{
id: 3,
url: "https://jsonplaceholder.typicode.com/posts",
},
];
const Component = () => {
const [abilities, setAbilities] = useState([]);
async function fetchURL(url) {
const res = await axios.get(url);
const data = res.data;
return data;
}
async function fetchAllUrls() {
const data = await Promise.all(
urls.map(async (url) => {
return await fetchURL(url.url);
}),
);
setAbilities(data);
}
useEffect(() => {
fetchAllUrls();
}, []);
return (
<div>
{abilities.map((aba, rootIndex) => (
<ul key={rootIndex} className="">
{aba.map((ability, index) => (
<li key={`${rootIndex}-${index}`} className="inline px-3">
{ability.title}
<p>{ability.effect}</p>
</li>
))}
</ul>
))}
</div>
);
};
export default Component;
Of course, this solution is not very good for production apps because loop requests and fetch data happened. but this is working fine!
Upvotes: 1
Reputation: 4045
You cannot write a function definition within JSX. You can only write expressions.
This is not allowed within JSX:
{async function fetchURL(){/*••• Function definition •••*/}}
But this is:
{fetchURL()}
Upvotes: 0
Reputation: 1586
The structure of your query is not correct. There are a lot of ways to fix this problem, but essentially you need to separate the data call from the component display instead of trying to do both all at once.
This is usually done with React Hooks, and there are numerous examples out there of how to accomplish this. Like this one.
The thing to notice about that approach is that it uses the useState
and useEffect
hooks to separate the problem into several parts. This approach has the benefit of being reusable and scalable, as it can be easily adjusted to solve any data-fetching problem.
So in the example given in the link I posted, the solution is broken into different pieces:
// Library imports
// Component definition
function someFunction () {
// useEffect hook for polling
useEffect(() => {
// Check to see if data needs to update and if it does
// call getPost()
}, [])
// useState hook for managing state and making
// it available to the rest of the component
const [someState, setSomeState] = useState(state)
const getPost() => {
// This is where the data call happens,
// Query the API and
// pass the results are passed to someState
}
// merge the results of someState() with the UI
render(
// map the data in someState
// to the UI elements.
)
}
Generally speaking, you're going to want to separate your concerns as much as you can when computer programming. If you're trying to grab state, set state, and render state all in one big chunk of code, it's probably time to slow down and re-think your approach to handle each problem one at a time.
Try re-writing your component in something closer to this form and ask again and I'm glad to help you get where you're going.
Upvotes: 0