React

[React] socket.io-client listen muntlple events in useEffect

hazel__ 2022. 5. 4. 14:13

 

React 와 Typescript를 사용하여 프로그램을 작성하는 과정에서 발생한 오류이다.

 

문제 상황

 

아래 코드와 같이

function component 내에서 useEffect 를 사용하고, 해당 훅 내에서 socket 통신을 하는 상태이다.

function testFunc() {
	useEffect(()=>{
		socket.on("test", ()=>{
			console.log("test!");
		});
	});	
	return (
		<div>testFunc</div>
	);
}

 

해당 코드에서 socket 통신을 하는 경우, 소켓을 듣는 횟수가 중복해서 발생했다.

//1회
test!

//2회
test!
test!

//3회
test!
test!
test!

socket.emit(”test”) 는 동일하게 한 번만 실행했음에도 socket.on(”test”)는 실행할수록 증가했다.

 


해결 방법

 

아래의 두 글을 통해 힌트를 얻었다.

 

https://github.com/socketio/socket.io-client/issues/1306

 

socket.io-client listening same event multiple times in reactjs · Issue #1306 · socketio/socket.io-client

Hello, I am creating a group chat application in reactjs, nodejs(expressjs) and socket.io. My code is all about 20-30 lines. When I clicked on send button, An event is emitted and I am listening th...

github.com

Why I having multiple requests to the server when listening to socket event inside useEffect?

 

Why I having multiple requests to the server when listening to socket event inside useEffect?

I am getting multiple requests although only one event is emitted inside node js server. I want to rerender my component only once when event is emitted from the server in order to notify the user ...

stackoverflow.com

 

 

Unsubscribe should be done on unmount.

 

컴포넌트가 unmount 될 때, socket.on을 꺼야한다.

 

클래스형 컴포넌트에서는 componentWillUnmount() 함수를 사용하여 해결할 수 있고,

함수형 컴포넌트에서는 useEffect 함수에서 return 내에 함수를 작성하여 해결할 수 있다.

이때, return 함수가 실행될 때, 내부 함수가 실행되어야 하므로 화살표 함수를 사용하여 작성해야 한다.

function testFunc() {
	useEffect(()=>{
		socket.on("test", ()=>{
			console.log("test!");
		});
		return (()=>{
			socket.off("test");
		});
	});	
	return (
		<div>testFunc</div>
	);
}

 

만약, return 함수 내에서 화살표 함수를 사용하지 않는 경우

useEffect(()=>{
	socket.on("test");
	return (socket.off("test"));
});

페이지가 unmount 될 때가 아닌 렌더링이 되면서 해당 함수가 실행되어 socket을 듣기 전에 종료된다.