이마트 피코크 사이트를 만들면서 상품 리스트 불러오기, 장바구니, 상품 좋아요 누르기 등 다양한 기능들을 구현하고 있다. 내가 맡았던 카테고리별 상품 리스트 불러오기 페이지를 개발하던 중, 막히는 부분이 생겼다.
KOREAN
에 마우스를 올려놓으면 한국 음식 리스트를 불러오는데,
CHINESE
에 마우스를 올려놓으면 중국 음식 리스트를 불러온다.
카테고리별 상품 리스트가 서로 다른 페이지에 있는 것이 아니라, 같은 컴포넌트인데 데이터만 바꿔끼우는 형식이었다. 이때까지 componentDidMount
를 써서 초반에 컴포넌트에 띄울 데이터를 불러와 state에 저장시키는 방식을 썼는데, 이제는 유저가 hover한 카테고리 값이 바뀔 때마다 데이터를 바꿔주어야 했다.
React를 사용하면서 흐름적인(?) 부분에서 막힐 때 LifeCycle 관련된 문제일 때가 많아서 찾아보던 중, componentDidMount를 발견했다 👀
componentDidMount는 처음에 컴포넌트가 render 되고난 후 맨처음 한번만 실행한다. 통신으로 GET한 값을 state에 저장하는 등, 초기값을 설정할 때 주로 이 함수를 이용한다.
componentDidUpdate는 this.setState()
함수가 실행되거나, 부모에서 내려준 props 값이 변경되었을 때
실행하는 함수이다. 즉, 데이터에 변화가 일어나서 다시 렌더링 해주어야 할 때 실행된다.
내가 해결해야할 문제는 바로 이 함수를 통해서 해결할 수 있었다.
부모에서 categoryId를 props로 내려주면, 그 categoryId값에 맞는 API를 호출해서 상품 목록을 띄우는 형식이었다.
부모에서 categoryId가 바뀌었을 때 다른 API를 부르게 해야 했는데,
이는 부모에서 내려준 props 값이 변경되었을 때
이므로, componentDidUpdate를 사용하면 되는 것이었다.
그래서 componentDidMount에 있던 fetch를 componentDidUpdate에 옮기고 실행시켜 보았다. 그랬더니 카테고리에 마우스 hover를 할 때마다 아주 데이터가 잘 바뀌었다. 문제를 해결했다고 좋아하고 있던 찰나에 콘솔창을 열였는데
세상에... 무한반복이 일어나고 있었다🤦♀️ 렌더링을 수도없이 해버리는 일이 발생하였다. 필요한 부분만 렌더링하는 것이 리액트의 장점인데, 저렇게 렌더링이 무한반복되면 그게 무슨 의미인가 싶었다.
componentDidUpdate는 render()
와 마찬가지로 state값이 변경될 때 실행이 된다. 그런데 그 안에서 this.setState()
를 부르게 되면 무한루프에 빠지게 된다.
componentDidUpdate 함수는 인자값으로 prevProps
와 prevState
, 즉 이번 props값과 이전 state값을 가진다. setState()
를 하려면 조건으로 prevProps와 현재 props값이 다를 때
를 걸어주어야, props값이 바뀌었을때만 실행하면서 무한 렌더링이 사라진다.
이렇게 조건문으로 감싸주었더니, 더 이상 무한 렌더링이 일어나지 않고 카테고리에 따른 상품 리스트를 불러올 수 있었다.