Reputation: 109
Below is the code to fetch some data
useEffect(async (id) => {
// const data = await redditFetch(id);
async function redditFetch(id){
try {
const {data:{data}} = await axios.get(`https://www.reddit.com/search.json?q=${id}&limit=50`);
const {children} = data;
return children.map(data=> data.data);
} catch (error) {
console.log(error);
}
}
const data = redditFetch(id);
setData(data)
},[setData])
console.log(Data);
And this is the promise returned:
Promise {<pending>}
__proto__: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: Array(50)
What I want is the Array inside the PromiseResult.
I've also tried another away using async await like this which returns a proper array.
const PostPage = () => {
const {id} = useParams();
const [Data, setData] = useState([])
useEffect(async (id) => {
// const data = await redditFetch(id);
async function redditFetch(id){
try {
const {data:{data}} = await axios.get(`https://www.reddit.com/search.json?q=${id}&limit=50`);
const {children} = data;
return children.map(data=> data.data);
} catch (error) {
console.log(error);
}
}
const data = await redditFetch(id);
setData(data)
},[setData])
console.log(Data);
But with this comes a bloody warning that I can't get rid of:
index.js:1 Warning: An effect function must not return anything besides a function, which is used for clean-up.
It looks like you wrote useEffect(async () => ...) or returned a Promise. Instead, write the async function inside your effect and call it immediately:
useEffect(() => { async function fetchData() { // You can await here const response = await MyAPI.getData(someId); // ... } fetchData(); }, [someId]); // Or [] if effect doesn't need props or state
So, my dear coders, tell me what to do???
Upvotes: 0
Views: 1656
Reputation: 790
I did a sample demo with the post code:
const data = redditFetch(id);
the async
functions will return a Promise
. You have to use await
, but React will warn you to not transform the useEffect
callback in async
functionuseEffect
.setDate
in your useEffect
dependency array. In this case, you can leave this empty to run just one time. Also, don't put the date
because will re-render in an infinite loop. If you need some conditional just remove the dependency array and put some conditional to run setDate
.I had to mock the
id
in the query parameter to be possible to work with API
CODE:
import axios from "axios";
import { useEffect, useState } from "react";
import "./styles.css";
async function redditFetch() {
try {
const {
data: { data }
} = await axios.get(`https://www.reddit.com/search.json?q=01&limit=50`);
const { children } = data;
return children.map((data) => data.data);
} catch (error) {
console.log(error);
}
}
export default function App() {
const [data, setData] = useState([]);
const Data = data.map((redditContent) => {
return (
<div key={redditContent.name}>
<h2>{redditContent.title}</h2>
<hr />
</div>
);
});
useEffect(() => {
(async function () {
const redditResponse = await redditFetch();
console.log(redditResponse);
setData(redditResponse);
})();
}, []);
return <div className="App">{Data}</div>;
}
ALTERNATIVE: CLEANER APPROACH (No anonymous function)
If you don't like of anonymous function approach, you can use this one:
async function updateRedditPosts() {
const redditResponse = await redditFetch();
console.log(redditResponse);
setData(redditResponse);
}
useEffect(() => {
updateRedditPosts();
}, []);
Upvotes: 0
Reputation: 154
Anything return from useEffect supposed to be clean up while component unmount. Better you may invoke setData function there instead of return.
On the other hand, you may use immediate invoke function (IIF) then you do not need to resolve the promise that return from redditFetch function.
Upvotes: -1