Reputation: 631
I'm trying to use useEffect with some async functions, however when the dependency in the dependency array changes, only the non async code gets called in useEffect.
useEffect( async () => {
console.log(account);
const web3 = await getWeb3();
const acc = await loadAcc(web3);
await loadContract(web3, acc);
}, [account])
When my account state variable changes, useEffect gets invoked again, but only the console.log(account) statement will get executed.
How should I work around this problem?
Upvotes: 0
Views: 1282
Reputation: 3001
useEffect
expected to return either void or a function( the cleanup function ). When you make the function you pass to useEffect
as an async, the function will return a promise.
One way to do it is,
useEffect( () => {
const init = async () => {
const web3 = await getWeb3();
const acc = await loadAcc(web3);
const res = await loadContract(web3, acc);
// do something after the async req
}
init();
}, [getWeb3, loadAcc, loadContract])
Or else,
const [web3, setWeb3] = useState(null);
const [acc, setAcc] = useState(null);
useEffect(() => {
getWeb3();
}, [getWeb3])
useEffect(() => {
if (!web3) return;
loadAcc(web3);
}, [web3, loadAcc])
useEffect(() => {
if (acc && web3) {
loadContract(acc, web3);
}
}, [acc, web3, loadContract])
const getWeb3 = useCallback(async () => {
// do some async work
const web3 = // async call
setWeb3(web3)
}, [])
const loadAcc = useCallback(async (web3) => {
// do some async work
const acc = // async call
setAcc(acc);
}, [])
const loadContract = useCallback(async (acc, web3) {
// do anything
}, [])
Upvotes: 1
Reputation: 4086
The function passed into useEffect
cannot be async. You can define an async function inside the useEffect and then use the then/catch syntax.
Further, also pass in all the functions that are defined outside of the useEffect (that you are calling) as a dependency to useEffect
useEffect(() => {
const myAsyncFunc = async () => {
console.log(account);
const web3 = await getWeb3();
const acc = await loadAcc(web3);
await loadContract(web3, acc);
}
myAsyncFunc.catch(console.error);
}, [account, getWeb3, loadAcc, loadContract])
Upvotes: 2