우선 이 코드를 한 번 보자
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()
}, [])
첫 렌더링 시에 받아온 값을 setState 함수를 사용하여 값을 넣어주고 useEffect가 끝나기도 전에 그 값을 이용하려하여 작업을 하려하여 내가 원하는 작업을 하지 못했다.
위와 같이 코드를 수정하니, 첫 렌더링 시에도 작업이 원활하게 잘 되었다.