const Home = () => {
const [blogs, setBlogs] = useState(null);
const [isPending, setIsPending] = useState(true); //Loading메세지 보여주기 위함
const [error, setError] = useState(null);
//Error 상황시 메세지 보여주기 위함
useEffect(() => {
//setTimeout은 Loading을 명시적으로 보여주기 위해서 1초 무의미하게 쉬는 것임
setTimeout(() => {
fetch("http://localhost:8000/blogs")
.then(res => {
//fetch를 통해 받아온 res객체 안에
//ok 프로퍼티가 있음
if (!res.ok) {
throw Error("could not fetch the data that resource");
}
return res.json();
})
.then(data => {
setBlogs(data);
setIsPending(false);
setError(null);
//정상적으로 데이터가 오면
//Loading, error메세지가 출력이 되지 않게
})
.catch(err => {
setIsPending(false);
setError(err.message);
//에러시 Loading메세지 사라지고
//에러메세지만 보이도록 설정
});
}, 1000);
}, []);
return (
<div className="home">
{error && <div>{error}</div>}
{isPending && <div>Loading...</div>}
{blogs && <BlogList blogs={blogs} title="All Blogs" />}
</div>
);
};
fetch를 통해서 데이터를 받아올 때 그 데이터가 통신상의 문제 등 여러 이유로 에러가 발생할 수 있다. 그럴 때 에러 상황을 예외처리를 해줘야 하는데 이 때 catch
를 사용해서 에러 상황을 핸들링할 수 있다.
아래 코드에서 fetch 함수 부분을 보면 마지막에 .catch()
를 사용해서 에러 객체를 매개변수로 받아오는 것을 볼 수 있다. 그 에러를 통해서 에러 메세지를 출력할 수도 있다.
예를 들어 json-server를 터미널에 ctrl + C
를 눌러서 서버를 다운시키고 나서 코드를 재실행시키면 catch
함수 내에 있는 코드가 실행이 된다.
그런데 아예 서버가 다운돼있어서 생기는 에러가 아니라 데이터를 어떻게든 가져오지만 그 데이터 안에 에러가 있는 경우는 catch 구문으로 들어오지 않는다. 그래서 fetch를 통해서 받아오는 응답객체인 (위 코드의 경우)res의 상태를 검사하는 방법도 있다.
응답객체인 res 에는 ok
프로퍼티가 있는데 이를 통해서도 응답데이터에 에러가 있는지를 확인할 수 있다. 이렇게 에러가 발생한 경우에는 throw Error()
를 통해서 에러를 던져주면 이 에러를 catch 구문에서 받아서 에러에 대한 예외를 처리해주게 된다.
예를 들어 endpoint 주소가 "http://localhost:8000/blogs"
인데 이 주소를 조금 다르게 하거나 하면 연결은 되지만 응답객체의 ok 프로퍼티가 false 값이 돼서 돌아온다. 그럴 때 throw Error()
가 작동해서 catch 구문에서 예외가 처리된다.