1

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>
);
0xRLA
  • 3,279
  • 4
  • 30
  • 42

1 Answers1

1

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>;
Abito Prakash
  • 4,368
  • 2
  • 13
  • 26