useState 재활용하면 어떨까?

camel·2023년 8월 11일
0

Project Refactoring

목록 보기
6/6
post-thumbnail

게임 페이지를 처음 만든 것은 4월 말 때쯤으로 기억한다.
이전 프로젝트에서 useState를 많이 만들어서 9줄 이상을 차지한 페이지도 있어서
마음에 들지 않았다.

왜냐하면 긴 로직은 가독성이 떨어지고 유지보수에 좋지않다.

그래서 나의 고민은 여러 개 usestate를 1개의 객체로 만들어서 관리해보자 라는 아이디어에 도달했다.

이러한 방법은 좋은 시도였지만 거기에 나아가서
useState의 역할이 다한다면 이것을 재활용해서 메모리까지 아껴보면 어떨까?
하는 생각에 도달했다.

그리고 이러한 관점에서 느꼈던 생각들에 대하여 정리하였다.


useState 여러 값들을 1개의 배열로 만들어 보자!

useReducer로도 해볼까 했지만 내 생각에 useReducer는 직관성이 떨어진다.
(useState보다 작성해야 하는 로직도 길다)

그래서 내가 생각한 방법은 useState를 배열로 만들고

0번, 1번, 2번 이런 식으로 관리하는 것이 각각 다르게 사용하는 아이디어였다.

일단 작성한 로직을 보자

	const [isModal, setIsModal] = useState<[boolean, Round]>([
		true,
		init
	]);

	const [isCheck, setIsCheck] = useState<[boolean, number]>([
		true,
		3
	]); //3은 초기화//4는 끝

isModal같은 경우에는 첫번째 값은 모달이 완료되었는지 여부를 반환하고
두번째 배열 값은 라운드 값을 반환한다.
(원시값으로 나누어진 것들을 배열로 묶어서 관리한다.)

isCheck는 원시값으로 나누어진 것들을 배열로 묶어서 관리하는 것에 그치지않고 재활용까지 하는 로직이다.

요약하면 isModal은 배열로 2개의 상태를 관리하고
isCheck는 상태관리도 2개이상을 하고 재활용까지 시도했다.

isCheck 기능


해당 사진을 클릭하면 isCheck 0번 값은 false로 바뀌고
애니메이션 발생한다.
이후에는 다시 true로 바뀐다.

  • isCheck 0번 값은 사진 Animation 관리하는 값이다.

isCheck의 1번째 값은 0, 1, 3, 4가 들어올 수 있는데

먼저 초깃 값인 3은 뽑힌 게 없음을 의미하고,
0, 1은 1번 혹은 2번 사진 고름을 의미한다.
4는 게임이 전부 끝났다는 것을 의미한다.

isCheck[1] 값 재활용 플로우

게임 시작 시 3을 유지하고 진행중에는 3 값을 쓰지 않는다.
그래서 진행중에는 0과 1이 들어와서 재활용을 하고
게임이 끝난 뒤에는 다시 원래의 역할로 돌아가 4를 넣어줘서 게임을 마무리한다.

결론

재활용하는 방식은 좋았지만, 유지보수에 있어서 경우의 수가 늘어난다.
동적으로 용도가 변하기 때문에 유지보수에 어렵다고 생각하여서
재활용은 좋은 선택이 아니다.

하지만 장점도 있었다.

한번 쓴 객체를 재활용했기 때문에 2개에 쓸 메모리를 1개의 객체에 사용하여서 메모리 사용량을 감소시켰다.
만약에 메모리 감소량이 많다면, 이 방법을 체계적으로 패턴화해 유지보수를 좋게하면 하나의 방법이 되지 않을까?라는 생각도 해보았다.
(중요도가 유지보수 < 성능이라면!)

그래서 찾아보았다. 어느 정도의 영향을 끼치는지..?

JavaScript 엔진은 객체와 원시값을 관리하는 방식에 많은 최적화를 수행하므로, 이러한 작은 변경은 메모리 사용에 큰 영향을 미치지 않을 것이라 한다.

두 방식 사이의 선택은 메모리 사용량보다는 코드의 가독성, 유지보수성, 로직의 복잡도 등을 고려하여 결정하는 것이 좋다고 한다.

객체가 아니라 원시값으로 따로 관리하면 각 상태를 독립적으로 업데이트할 수 있으므로 로직이 단순해질 수 있어서 좋다..

그리고 객체로 관리하면 불변성도 관리해 주어야 하고, 로직이 복잡해서 유지보수에 좋지 않다.

정리

값을 재활용하는 것은 메모리를 아낄 수 있지만
그 양이 너무 미미하다.
단점이 더 크므로 지양해야한다.

또한 여러 개 값을 하나의 useState로 관리한다면
로직도 짧아지고 심플해지지만
네이밍을 통해 의미를 알기 어렵고 구분하기 어려워 유지 보수면에서 아쉽다.

거기다가 props으로 내려줄 때 원시값이 아닌 객체이기 때문에
렌더링을 발생시킬 리스크가 존재한다.

예전에는 useState값 업데이트를 여러번을 해주었는데 요즘에는 Auto Batching을 처리해주기 때문에 useState 갯수를 늘리고 원시값으로 써주는 것이
한개의 객체로 관리하는 것보다 성능면에서 우수할 것이다.

결론은 메모리 사용량을 우선시하기보다는 코드의 가독성, 유지보수성, 로직의 복잡도를 우선시해야한다!!



수정 로직


수정 전

수정 후

1개였던 것을 3개로 나누어서 관리하니 줄이 길어진 것은 마음이 아팠지만,
한 로직마다 의미가 명확해 유지보수 측면에서 좋았다.

끗!

profile
화이팅~ 가보자구

0개의 댓글