side Effect란, 순수 함수적인 특징에 위배되는 기능들을 말한다.
순수 함수?
- 어떤 값이 들어왔을 때, 일관된 값만 나와야 한다.
- 즉, 어떠한 전달 인자가 주어질 경우, 항상 똑같은 값이 리턴되어야 한다.
- 그래서 예측이 가능한 함수이기도 하다.
- 인자로 받아오지 않은, 외부에 존재하는 변수의 값을 사용한다거나 외부에 존재하는 변수의 값에 영향을 미치는 경우엔 순수함수가 아니다.
side Effect의 예시로는 네트워크 요청, fetch API 사용, LocalStorage, Timer 같은 React와 상관 없는 API 사용 등이 있다.
그렇다면 이런 side Effect는 어떻게 다루어야 할까? React는 이 경우 side Effect를 다루기 위한 Effect Hook인 useEffect를 제공한다.
useEffect(함수, [ ]);
- 첫 번째 인자인 함수 --> side Effect 실행할 함수 , 우리가 useEffect로 실행시킬 함수
- 이 함수는 두 번째 인자가 없을 경우,
- 컴포넌트 생성 후 처음 화면에 렌더링 될 때
- 컴포넌트에 새로운 props 전달되며 렌더링 될 때
- 컴포넌트의 state (상태)가 바뀌며 렌더링 될 때
- 실행된다.
- 두 번째 인자인 배열 --> 종속성 배열이라고 부르며, 이 배열 안에 담긴 값이 변경될 때, 위의 함수가 실행된다.
- 즉, 변경 되는지 안되는지 지켜봐야 할 값들이 들어있는 배열이다.
- 두 번째 인자인 배열이 빈 배열로 주어질 경우, 지켜볼 값이 없다는 것이기 때문에 최초 1번만 실행된다. (컴포넌트가 처음 생성될 때만 실행됨)
이제 예시를 살펴보며 useEffect에 대해 더 자세히 알아보도록 하자.
- condition의 조건이 바뀔 경우 side Effect가 발생하는 함수 (getFlight(condition) 함수)를 Main 컴포넌트에서 호출해야 한다.
- < LoadingIndicator /> 컴포넌트 이용하여 로딩 화면을 제공해야 한다.
const [isLoading, setIsLoading] = useState(true);
로딩 화면을 만들기 위해서 일단 로딩 상태를 담을 state 변수 isLoading을 만들어주고 초기값을 true로 주었다. (초기값 true -> 로딩중)
useEffect(() => {
setIsLoading(true);
getFlight(condition).then((filtered) => {
setFlightList(filtered);
setIsLoading(false);
});
}, [condition]);
useEffect 사용하기
getFlight(condition) 함수는 인자로 들어온 객체 (depature, destination의 value값 들어있는 객체)를 검색 결과에 따라 필터링해주는 함수이다.
우리는 로딩중일 때, 검색 결과에 맞게 departure과 destination을 필터링해주어야 한다.
따라서 로딩중일 때, getFlight(condition) 함수를 사용한다.
getFlight(condition) 함수에 따라 필터링이 되었다면, 이 필터링된 값을 state 변수인 flightList에 넣어줄 필요가 있다.
그래서 .then 을 사용하여 필터링되었을 경우, state 변경 함수인 setFlight에 필터링된 값을 넣어준다.
여기까지 완료가 되었다면 로딩도 완료가 된 것이다. 따라서 로딩 상태를 false로 준다. (로딩중 x)
{isLoading ? <LoadingIndicator /> : <FlightList list={flightList} />}
이제 마지막으로 isLoading의 값이 true 일 때, false 일 때 출력될 값을 삼항연산자로 연결해주면 된다.
isLoading 이 true 일 때는 (로딩 중 일때는) 별도로 구현되어 있는 < LoadingIndicator /> 컴포넌트를 출력한다.
isLoading 이 false 일 때는 (로딩 중이 아닐 때는) getflight(condition) 함수를 통해 필터링된 flightList를 출력한다.