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)
}
}
CodePudding user response:
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])
CodePudding user response:
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.
CodePudding user response:
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.)