useEffect 내에서의 setState

JunSeok·2022년 9월 21일
0

에러 해결

목록 보기
5/15
post-custom-banner

우선 이 코드를 한 번 보자

	const [themeInfo, setThemeInfo] = useState({})

    useEffect(() => {
        const getImages = async () => {
          try {
            const response: any = await apiInstance.get(`/movies/theme`)
            const themeResponse = response.data

            setThemeInfo(themeResponse)
            
            cosnt themeList = Object.keys(themeInfo)
            themeList.map((obj) => {
            	....
            }
          } catch (e) {
            console.log(e)
          }
        }
        getImages()
    }, [])
	
	console.log(themeInfo)

다음 코드를 실행하면 내가 원하는 작업을 할 수 없음을 알게 될 것이다.

첫 렌더링 시, useEffect 내에서 DB로부터 받아온 값을 setState 함수를 사용하여 값을 넣어주고 useEffect가 끝나기도 전에 그 값을 이용하여 이후 작업을 곧바로 하려 했고, 당연히 실패했다.

그 이유는 useEffect는 페이지가 렌더링 된 이후에 실행되기 때문이다.

이러한 이유로 useEffect 내에서 setState함수를 통해서 상태변화를 해줘도 첫 렌더링한 페이지는 상태변화를 알아차리지 못 한다.

평소에는 이 같은 경우를 알아차리지 못 할 수 있다.
하지만 useEffect 내의 setState 함수를 통해 이루어진 상태변화 결과가 첫 렌더링 시 바로 화면에 보여지는 경우에는 치명적일 수 있다.
(themeInfo에 담긴 image 파일을 첫 렌더링 시에 화면에 띄워줘야 하는 경우에 곧바로 알 수 있다.)

처음 몰랐을 때는 꽤 당황했었다.
첫 렌더링 때 안되고, 한 번 더 렌더링을 하면 잘 동작했기 때문이다.

이를 해결하기 위해 나는 이전의 코드를 다음과 같이 수정해주었다.

	const [themeInfo, setThemeInfo] = useState({})

    useEffect(() => {
        const getImages = async () => {
         	try {
            	const response: any = await apiInstance.get(`/movies/theme`)
           	    const themeResponse = response.data
				const themeList = Object.keys(themeResponse)

            // 테마별 영화 모음
            	const themeInfoBox = {}
            	themeList.map((obj) => {
                	themeInfoBox[obj] = themeResponse[obj]
            	})
            	setThemeInfo(themeInfoBox)
        	}
        getImages()
    }, [])
  1. useEffect 내에서 변수를 하나 만들어줬다.
  2. DB에서 받아온 값을 이용하여 필요한 작업을 한다.
  3. 그 값을 새로 만든 변수 themeInfoBox에 넣어준다.
  4. useEffect 바깥에서 useState로 선언한 변수에 값을 넣어주기 위해, setState함수를 사용하여 값이 변화된 것을 알려주고 다시 렌더링할 것을 요청한다.
  5. 다시 렌더링 되어 themeInfo에 성공적으로 작업한 값이 들어갔다.

첫 렌더링 시에 받아온 값을 setState 함수를 사용하여 값을 넣어주고 useEffect가 끝나기도 전에 그 값을 이용하려하여 작업을 하려하여 내가 원하는 작업을 하지 못했다.

위와 같이 코드를 수정하니, 첫 렌더링 시에도 작업이 원활하게 잘 되었다.

profile
최선을 다한다는 것은 할 수 있는 한 가장 핵심을 향한다는 것
post-custom-banner

0개의 댓글