보통 웹 애플리케이션을 만들 때는 백엔드에서 설계된 데이터베이스에서 데이터를 가져와서 화면에 보여주고 수정하는 등 CRUD를 통해서 동적으로 화면에 보여주는 것이 프론트엔드 개발자 역할 중 하나이다.
그런데 혼자서 데이터베이스를 다 만들고 통신하도록 셋팅하는 것이 번거롭기 때문에 공부 혹은 테스트 목적으로 json-server라는 프로그램을 사용할 수 있다.
create-react-app 을 이용해서 개발하는 환경에서 해당 디렉토리에서 npx json-server --watch data/db.json --port 8000
명령어를 터미널에 치면 패키지를 설치하게 되고 서버가 하나 실행된다. 그러면
Resources
http://localhost:8000/blogs
Home
http://localhost:8000
와 같은 결과화면이 터미널에 출력되는데 위의 Resource 주소를 브라우저에 치면 data 디렉토리 안에 있는 db.json 파일이 화면에 출력될 것이다. 바로 저 주소가 데이터베이스에 접근할 수 있는 endpoint가 되는 것이다.
물론 data 디렉토리 안에 db.json 이라는 파일이 미리 존재해야 하고 안에는 json 형식으로 테스트할 혹은 공부할 데이터가 정의돼있어야 한다. 필자의 데이터는 아래와 같다.
// data/db.json { "blogs": [ { "title": "My First Blog", "body": "Why do we use it?\nIt is a long established fact that a reader will be distracted by...", "author": "morello", "id": 1 }, { "title": "Opening Party!", "body": "Why do we use it?\nIt is a long established fact that a reader will be distracted by...", "author": "donglee", "id": 2 } ] }
이제 json-server를 이용해서 마치 백엔드의 데이터베이스에서 데이터를 가져오는 것과 같은 유사한 환경이 마련이 되었다.
//Home.js
import { useState, useEffect } from "react";
import BlogList from "./BlogList";
const Home = () => {
const [blogs, setBlogs] = useState(null);
useEffect(() => {
//여기서는 async await 을 쓸 수 없다.
fetch("http://localhost:8000/blogs")
.then(res => {
return res.json();
})
.then(data => {
setBlogs(data);
});
}, []);
return (
<div className="home">
//여기서 js 문법인 && 를 사용하지 않으면
//map 함수를 null에 사용한다는 에러가 발생한다.
{blogs && <BlogList blogs={blogs} title="All Blogs" />}
</div>
);
};
우선 Home.js 코드를 보자. 보통 useEffect
함수를 활용해서 컴포넌트가 렌더링 될 때 갱신된 데이터를 가져와서 보여주기 때문에 useEffect
함수 안에서 endpoint에 접근해서 데이터를 가져오는 것을 볼 수 있다. 그런데 useEffect
함수 안에서 데이터를 가져올 때 써야 하는 async await
를 사용하면 프로미스 문제로 에러가 나기 때문에 then()
을 이용해서 데이터를 가져온다. useEffect
함수 안에서 사실 async await 를 사용할 수 있는데 그 방법은 아래 블로그를 참고하면 된다.
useEffect 안에서 async await 사용하는 방법
(https://velog.io/@he0_077/useEffect-%ED%9B%85%EC%97%90%EC%84%9C-async-await-%ED%95%A8%EC%88%98-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0)
위 코드를 다시 보면 최초에 useState
에서 null 로 state가 초기화되어있다. 그런데 server에서 json 파일을 받아오는 useEffect 부분에서는 어느 정도 시간이 걸리기 떄문에 처음에 컴포넌트를 렌더링할 때는 <BlogList>
컴포넌트에 props로 보내는 blogs가 null 이다. 그래서 아래 코드를 보면 blogs.map(...)
이 부분에서 null 값에 map을 하기 때문에 에러가 발생한다. 그 이유 때문에 js 문법인 &&
연산을 활용해서 blogs가 null이 아닌 경우에만 컴포넌트를 컴퓨터가 읽을 수 있도록 처리한 것이다.
export default Home;
//BlogList.js
const BlogList = ({ blogs, title }) => {
return (
<div className="blog-list">
<h2>{title}</h2>
//blogs가 null이면 map함수에서 에러가 발생함.
{blogs.map(blog => (
<div className="blog-preview" key={blog.id}>
<h2>{blog.title}</h2>
<p>Written by {blog.author}</p>
</div>
))}
</div>
);
};
export default BlogList;