I'm stuck on this problem that I really can't make sense of.
When trying to access the hash state variable from the listener function in useContractEvent it is undefined.
I can access the hash state variable outside of the listener function in useContractEvent but as soon as the event is triggered and I try to read the hash state variable inside the listener function it is undefined.
Is it a context issue?
const [hash, setHash] = useState<`0x${string}` | undefined>();
useContractEvent({
address: contract.address as `0x${string}`,
abi: contract.abi,
eventName: "SomeEvent",
listener(log) {
console.log(hash) // undefined
if (log[0]?.transactionHash != hash) return;
// never reached
},
});
const { write } = useContractWrite({
address: contract.address as `0x${string}`,
abi: contract.abi,
functionName: "someFunction",
args: [],
onSuccess(data) {
setHash(data.hash);
},
});
return (
<button onClick={() => write?.()}>
Go
</button>
);
Yes, the issue you're facing is likely due to a context problem related to closures and the asynchronous nature of useContractEvent and useContractWrite.
One approach is to use ref
to always access the latest value of hash
const hashRef = useRef<`0x${string}` | undefined>();
useContractEvent({
address: contract.address as `0x${string}`,
abi: contract.abi,
eventName: "SomeEvent",
listener: (log) => {
console.log(hashRef.current); // This will always log the latest value of `hash`
if (log[0]?.transactionHash !== hashRef.current) return;
// never reached
},
});
const { write } = useContractWrite({
address: contract.address as `0x${string}`,
abi: contract.abi,
functionName: "someFunction",
args: [],
onSuccess(data) {
hashRef.current = data.hash;
},
});
return <button onClick={() => write?.()}>Go</button>;