Please, I'm a beginner. I want to fetch data from an Api and save it as a component in my react app, such that I will be able to export this component into other components and as such tap in into its data from each of those other components.
To do this, I tried using this code:
var data=[] ;
async function add(){
try {
const response = await fetch('https://api.tvmaze.com/search/shows?q=all#')
const json = await response.json()
console.log(json)
for (var i=0; i<json.length; i ){
data.push(json[i])
}
return data
}catch(error){
console.log("error", error)
}
}
add();
export default data;
This however doesn't seem to work well as it records a data length of zero in other components but when logged in the console, it gives the actual length of the array.
Please help me out.
CodePudding user response:
let's say you are having your function at util.js as follow
var data=[] ;
async function add(){
try {
const response = await fetch('https://api.tvmaze.com/search/shows?q=all#')
const json = await response.json()
for (var i=0; i< json.length; i ){
data.push(json[i])
}
return data
}catch(error){
console.log("error", error)
}
}
export default add;
and in your place where you want to use as follow
import add from './util.js';
add().then((data => console.log(data)))
CodePudding user response:
Use a parent component with state to act as the "single source of truth" for the data. Use an useEffect hook to initially load the data from the API into state at which point the components that rely on that data will re-render. In this case List
will render a list of show names wrapped in an anchors pointing to the show URL.
Note: I've had to use conventional fetch
...then
in this contrived example as snippets don't like async/await
but you can swap that out should you prefer.
const { useEffect, useState } = React;
// Pass in the API endpoint to the App component
function App({ api }) {
// Initialise state
const [ data, setData ] = useState([]);
// Using an empty dependency array (`[]`) so that the effect
// runs _once_ when the component is mounted call `getData`
// with `fetch` then parse the data, then set the state
// with `setData` using the parsed data
useEffect(() => {
function getData(api) {
fetch(api)
.then(res => res.json())
.then(data => setData(data))
.catch(err => console.log(err));
}
getData(api);
}, []);
// If `data` is empty just return a "Loading"
// message for the time-being
if (!data.length) return <div>Loading</div>;
// Otherwise render the List component passing in
// the state as its data property
return <List data={data} />
}
// List accepts a data property, and you can `map`
// over that array to produce a list of anchored items
function List({ data }) {
return (
<ul>
{data.map(obj => {
const { show: { url, name } } = obj;
return (
<li>
<a href={url}>{name}</a>
</li>
);
})}
</ul>
);
}
const api = 'https://api.tvmaze.com/search/shows?q=all';
// Pass in the API endpoint as an App property
ReactDOM.render(
<App api={api} />,
document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Additional documentation
CodePudding user response:
You can make a function for an api call and use it anywhere in you component like below
async function add(){
try {
const response = await fetch('https://api.tvmaze.com/search/shows?q=all#')
const json = await response.json()
return json.data;
}catch(error){
console.log("error", error)
}
}
export default add;
import React, {useState, useEffect} from 'react';
import add from './add';
const App = () => {
const [data, setData] = useState([]);
useEffect( async()=> {
const result = await add();
setData(result);
},[])
return (
<>
{data.map((item) => <h1>item[anyKeyIfExist]<h1>)}
</>
);
};