I am using 2 useEffects on a file and the second useEffect is dependent on the first one.
Is there a way of delaying the second useEffect until the data from the first useEffect has been gotten?
const params = useParams()
const [userData, setUserData] = useState({})
const [followers, setFollowers] = useState([])
useEffect(() => getUser(params.id), [])
useEffect(() => {
getFollowers(userData?.user?._id, auth.token)
}, [])
const getUser = async (id) => {
const res = await getUserProfile(id)
if (res) {
setUserData(res)
}
}
const getFollowers = async (id, token) => {
const res = await getUserFollowers(id, token)
if (res) {
setFollowers(res)
}
}
Execute second useEffect only if first useEffect has retrieved its data:
const params = useParams()
const [userData, setUserData] = useState(null) // initialize userData as null
const [followers, setFollowers] = useState([])
useEffect(() => getUser(params.id), [])
useEffect(() => {
// wait until userData is defined to make the second call
if (userData)
getFollowers(userData?.user?._id, auth.token)
}, [userData])
Make one useEffect and make it async and fetch both API functions there with await. Otherwise you also have a solution to add userData in 2nd useEffect as dependency which you can add in their dependency array.
It looks like you want to get followers any time userData changes, so make that a dependency of the effect:
useEffect(() => getUser(params.id), [])
useEffect(() => {
const id = userData?.user?._id
if (id) {
getFollowers(id, auth.token)
}
}, [userData?.user?._id]) // <=====
That will re-run the followers effect whenever that ID changes.
Alternatively, you could combine them:
useEffect(() => {
getUser(params.id), [])
.then(userData => getFollowers(userData?.user?._id, auth.token))
.catch(error => { /* ...handle/report error here...*/ })
}, []);
const getUser = async (id) => {
const res = await getUserProfile(id)
if (res) {
setUserData(res)
}
return res // <==== Note returning the result as well as setting it
}
const getFollowers = async (id, token) => {
const res = await getUserFollowers(id, token)
if (res) {
setFollowers(res)
}
}
(In either case, the code should be handling rejeections from those async functions.)