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?
CodePudding user response:
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])
CodePudding user response:
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
}, [])