WavePortal.sol
에 선언된 event와 emit은 블록에 특정 값을 기록하고 출력하는 역할을 한다.
App.js
에서 이벤트 리스너를 추가해 랜더링 될 때마다 event가 출력되도록 해보자.
useEffect(() => {
let wavePortalContract;
const onNewWave = (from, timestamp, message) => {
console.log("NewWave", from, timestamp, message);
setAllWaves(prevState => [
...prevState,
{
address: from,
timestamp: new Date(timestamp * 1000),
message: message,
},
]);
};
if (window.ethereum) {
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
wavePortalContract = new ethers.Contract(contractAddress, contractABI, signer);
wavePortalContract.on("NewWave", onNewWave);
}
return () => {
if (wavePortalContract) {
wavePortalContract.off("NewWave", onNewWave);
}
};
}, []);
리액트에서 이벤트 리스너를 사용할 때는 useEffect 내에서 등록해야 한다. 그냥 사용하면 렌더링 시점이 구분되지 않기 때문에 에러가 난다. useEffect로 최초 로드 시 이벤트 리스너를 등록해서 이벤트를 감지를 시작하도록 하고, 메모리 누수를 방지하기 위해 unmount 시 이벤트 리스너 등록을 해제 해줘야 한다.
solidity에선 on
과 off
로 이벤트를 등록하고 해제할 수 있다.