I'm currently working on a React project. Using the Axios library, I need to get data from the API and write it to a variable.
Searching the web for this, I found the only option is via Promise.then()
, but that's not what I want, as the result is simply returned to the next Promise.then()
.
I need Axios to return the result and after that my function returns this result instead of with the tag so to speak. Sample code below. Thanks in advance.
function getData() {
let packsId = '11111';
if (packsId) {
return axios.get('http://localhost:8000/api/words?id=' packsId)
.then((response) => {
return response;
})
.catch((error) => {
return error;
});
}
else {
return <div>Doesn't exist</div>;
}
}
export default function WordsPack() {
let result = getData(); // here returned Promise, not Object with data
return <div>{ result }</div>
}
CodePudding user response:
If you wanna call let result = getData()
at the top level of your component as you showed in your example, you would wanna transform getData
to a custom hook, as an example like so:
import { useState, useEffect } from "react";
// ⚠️ Notice it start with "use":
export default function useGetData() {
const [result, setResult] = useState("Loading..."); // the data to show while fetching
useEffect(() => {
let packsId = "11111";
if (packsId) {
axios
.get("http://localhost:8000/api/words?id=" packsId)
.then((response) => setResult("Put the data you want from response here"))
.catch((error) => setResult("You can put the error message from error here"));
} else {
setResult("Doesn't exist");
}
}, []);
return result;
}
export default function WordsPack() {
let result = useGetData();
// ⚠️ If you call {result} in your div and result is an object, you will get an error.
console.log(result)
return <div></div>
}
CodePudding user response:
Usually in hooks like your getData
you will have a state in which you'll write the response when it arrives. The hook would return this state so any component can consume async data in what looks like a synchronous call.
function getData(packsId) {
const [data, setData] = useState();
const [error, setError] = useState();
useEffect(() => {
if (packsId) {
return axios.get('http://localhost:8000/api/words?id=' packsId)
.then(setData)
.catch(setError);
}
else {
setError("Doesn't exist");
}
}, [packsId]);
return {data, error}
}
export default function WordsPack(props) {
// data will update over time, triggering re-renders of WordsPack
let {data, error} = getData(props.packsId);
return <div>{ data['your-data-is-here'] }</div>
}
On the other hand in most cases people will use a package that does this (and way more). Something like tanstack's useQuery for example.
CodePudding user response:
you need to use Async/Await
async function getData() {
let packsId = '11111';
if (packsId) {
try{
return await axios.get('http://localhost:8000/api/words?id=' packsId);
}
catch(ex){
//error handle
}
}
else {
return <div>Doesn't exist</div>;
}
}
now to read the value you have to call with await in the same way
export default async function WordsPack() {
let result = await getData(); // here returned Promise, not Object with data
return <div>{ result }</div>
}
if it's inside component where you are calling getData() use useEffect and implement with state
export default async function WordsPack() {
const [result, setResult] = useState();
useEffect(() => {
(async() => {
const dataResult = await getData();
setResult(dataResult)
})();
})
return <div>{ result }</div>
}
for more references you can read https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function