[React] 동기적으로 setState() 사용하기

iamhyunji·2022년 5월 1일
4

Today Learn

목록 보기
1/1
post-thumbnail

들어가기 전에


내가 참여하는 프로젝트 중, 최근에 이미지 업로드 기능을 유지∙보수할 기회가 있었다.
유지∙보수 요청은 이미지 다중 업로드 기능 추가였다.

기존 이미지 업로드 컴포넌트는 파일 한 개씩만 업로드 가능한 구조였다.
이 구조에서 다중 업로드를 구현하는 방법은 아래 2가지였다.

  1. 데이터 구조를 한 번에 여러 개 파일을 담을 수 있는 구조로 변경
  2. 기존 코드에 Loop를 돌려 한 번에 하나씩 담는 형태

신규 개발이었다면 첫 번째 방법을 선택했겠지만, 다른 사람의 코드를 유지∙보수하는 입장에서 첫 번째 방법은 구조 변경 해야하는 영역이 컸고, 그로 인한 Side Effect도 걱정이었다.

그래서 나는 두 번째 방법을 선택했고, 결과는 처참했다.
다중 업로드를 하면, 여러 이미지가 업로드 되는 것이 아닌, 여러 이미지 중 마지막 이미지 하나만 화면에 render 되었다.

왜 이런 결과가 나왔고, 어떻게 이 문제를 해결했을까?
아래에서 자세히 알아보자.

setState는 무엇일까?


setState()는 컴포넌트 내에서 로컬로 사용하는 state 변수를 업데이트할 수 있는 함수이다.

setState()를 통해 state를 업데이트 하면,
state 변화를 감지해 화면이 re-render 된다.

const [imgCnt, setImgCnt] = useState(0)
const initImgCnt = () => {
	setImgCnt(0)
}

setState() 함수는 비동기적으로 동작한다.
모든 컴포넌트의 re-render가 시작하기 전까지 setState를 기다렸다가, 한 번에 state를 업데이트한다.

setState() 함수가 비동기로 동작하는 이유는 매번 state가 변할 때마다 화면을 re-render 한다면 성능 이슈가 발생할 수 있기 때문이다.
동기적으로 매번 업데이트 하는 것이 아닌, 비동기적으로 한 번에 업데이트 함으로써 불필요한 re-render를 방지한다.

동기적으로 setState하는 방법


언제 반환될지 모르는 변수를 어떻게 사용할 수 있을까?
조금 더 구체적으로, 비동기적으로 작동하는 setState()를 어떻게 동기적으로 사용할까?

방법은 아주 쉽다.
setState()의 인자로 객체가 아닌 updater 함수를 넘겨주면 된다.

const [imgCnt, setImgCnt] = useState(0)
const updater = (state, props) => {
	return state + 1
}

// 이미지 개수 증가
const increaseImgCnt = () => {
	setImgCnt(updater)
}

updater() 함수는 두 개의 인자를 받는다.
첫 번째 인자는 이전 state 값이고, 두 번째 인자는 props 값이 다.

updater 내부에서 updater() 함수는 우리를 현재 state 값에 접근할 수 있게 해, 우리가 state를 동기적으로 처리할 수 있게 한다.

const [imgList, setImgList] = useState([])

// 이미지 추가
const addImages = (file) => {
  	const updater = (prev) => [
    	...prev,
	    file,
    ]
	setImgList(updater)
}

위 방법을 통해서 나는 이미지 다중 업로드 시, 비동기로 이미지 업로드 되었던 문제를 해결했다.

요약


  • 로컬 state를 업데이트할 수 있는 setState() 함수
  • setState()는 비동기 함수이다
  • setState()에 updater 함수를 넘겨주면 동기적으로 작동한다

참고자료


profile
Lv0. 웹 개발 (❤️❤️❤️🤍)

0개의 댓글