React | 버튼 활성/비활성화 이슈 (feat. 리렌더링)

dev_hee·2022년 4월 13일
2

React

목록 보기
4/7

문제 발생

이벤트 참여 버튼에는 클릭시 이벤트 참여 API를 요청하는 핸들러가 등록되어있습니다.

API 요청을 보내기 전에 버튼을 비활성화 하고, 응답을 받고 나서 활성화 하도록 로직을 구현했습니다.

하지만 원하는 대로 동작하지 않음을 확인할 수 있었습니다.

아래의 코드는 이벤트 참여 API 대신에 setTimeout 함수로 2초뒤에 fulfilled 된 promise를 반환하는 함수를 사용하여 상황을 가정하였습니다.

원인 분석

위 코드의 문제점은 버튼의 활성/비활성 상태를 지역 변수 let isDisable 로 관리했다는 것입니다.

리액트 컴포넌트는 props와 state의 변화를 감지하여 리렌더링을 진행합니다. 리액트는 지역 변수의 변화를 감지하지 못하기 때문에 리렌더링을 하지 못했고, 따라서 버튼이 비활성화가 되지 않았습니다.

이를 해결하기 위해서는 useState 나 redux와 같은 상태관리 툴을 사용해서 관리해주면 됩니다. useState로 생성한 상태의 변화는 리액트가 감지하여 리렌더링 해줄 수 있습니다.

하단의 코드처럼 isDisableuseState로 상태로서 관리하였더니 정상적으로 동작함을 확인할 수 있었습니다.

버튼의 disabled 상태를 바꾸지 않는 경우

하지만 useState 를 사용해서 버튼 비활성화 상태를 관리하더라도 정상 동작하지 않을 수 있습니다.
버튼 엘러먼트의 disabled 속성값에 비활성화 상태를 전달하지 않고,
API 요청 함수 안에서 isDisable이 true일 때 return 하는 방법으로 API 중복 요청을 방지하면 정상 동작하지 않습니다.

useRef 로 컴포넌트 내의 변수 사용하기

useState 를 사용해서 버튼 비활성화 상태를 관리하더라도 버튼 태그에게 직접 disable 상태를 전달해주지 않는 경우엔, useState 가 비동기로 동작하기 때문에 API가 여러번 호출 되는 것을 방지할 수 없었습니다.

따라서 useRef 를 사용해서 API 호출 활성화 상태를 관리하였습니다.
isDisableAPI.current 에 API 호출 활성화 상태를 저장하면 이는 동기적으로 동작하기 때문에 비활성화 상태를 즉각적으로 적용할 수 있었습니다.

profile
🎨그림을 좋아하는 FE 개발자👩🏻‍💻

1개의 댓글

comment-user-thumbnail
2022년 4월 22일

꾸준하시네요 👍

답글 달기