useEffect를 사용하여 외부 API를 호출할 때 주의할 점

  1. Mount 시점인지 update 시점인지 확인
function ItemList() {
    const [users, setUsers] = useState([]);

    useEffect(() => {
        fetch('<https://jsonplaceholder.typicode.com/users>')
        .then(response => response.json())
        .then(responseUsers => {
            console.log(responseUsers);
            setUsers(responseUsers)
        });
    },
    []    // 의존성 배열을 빈배열로 줘서 useEffect의 콜백함수(비동기로 users 데이터 요청) 
					// 실행을 마운트 시점에만 동작하게 함(중요!!)
    ); 
    return (
        <div>
                {users.map(user => <Item user={user}/>)}
        </div>
    );
}

위 코드는 회원 목록을 렌더링하는 컴포넌트 함수이다.

useEffect를 사용해서 API를 호출하지만 then으로 콜백 처리 하는 부분에서 state의 변경을 주는 부분이 있음

이러한 경우에는 컴포넌트가 렌더링 되는 시점이 Mount 시점인지, Update 시점인지 확인 후 useEffect 의 두 번째 인자에 값을 지정해야함

만약, state 값이 바뀜에도 불구하고 두 번째 인자에 값을 지정하지 않았다면 해당 컴포넌트 함수는 내부적으로 무한히 호출되고 있을 것이다.

  1. 비동기 처리 시, 함수 진행 순서 확인
useEffect(() => {
		navigator.geolocation.getCurrentPosition((currentPosition) => {
				setPosition({
                    longitude: currentPosition.coords.longitude,
                    latitude: currentPosition.coords.latitude
                })
		});
		fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${position.latitude}&lon=${position.longitude}&appid=${API_KEY}`)
    .then(response => response.json())
		.then(json => console.log(json)
},

보통 fetch 를 통해서 외부 API를 호출 할 때, 필요한 Parameter 구성을 api 호출 전에 구성한다.

하지만, 위의 코드에서는 fetch api 시점에서 사용하는 변수를 정확인 인지가 불가능함

이러한 상황을 해결하기 위해서는 사전에 구성되는 Parameter 값을 구성하고 동기 형태로 fetch API를 호출해야 한다. → Promise 객체 사용

useEffect(() => {

    new Promise((resolve, reject) => {
        navigator.geolocation.getCurrentPosition((currentPosition) => {

            setPosition({
                longitude: currentPosition.coords.longitude,
                latitude: currentPosition.coords.latitude
            })

            resolve(currentPosition.coords);
        });
    }).then(coords => {
        fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${coords.latitude}&lon=${coords.longitude}&appid=${API_KEY}`)
        .then(response => response.json())
        .then(json => {
            console.log(json);
        });
    });
},
[]
);