React 데이터 저장, 불러오기

송이·2023년 1월 21일
4

React

목록 보기
3/3
post-thumbnail

Node 기반의 React는 여러가지 기능을 사용할 수 있는데
그 중 하나가 서버를 만들 수 있는 json server이다

npm install -g json-server로 터미널에서 설치할 수 있고
데이터베이스를 흉내낼 수 있는 서버를 만들 수 있다
사용하려면 몇가지 조건이 필요한데 그 조건을 살펴보자

🚩 db.json 파일 만들기

json server를 설치한 후 db.json파일을 만들어 준 후 db파일이 있는
경로에서 json-server --watch db.json으로 서버를 실행해준다

여기서 중요한 부분은 기존 React 포트 번호가 3000으로 돼있어
오류가 날 수 있다 json-server --watch db.json --port 3001
이런식으로 포트 번호를 바꿔주도록 한다

💡 axios 설치하기

npm i axios로 axios를 설치해준다
axios를 사용하여 db.json에 데이터를 저장해줄 것이다


🚩 input 연결하기

const BlogForm = () => {
  const [title, setTitle] = useState('');
  const [body, setBody] = useState('');
  const onSubmit = () => {
    axios.post('http://localhost:3001/posts', {
      title: title,
      body: body, 
    })
  };

  return (
    <div className="container">
      <div>
        <h1>Create a blog post</h1>
        <div className='titleAll'>
          <label className="title">제목</label>
          <input 
            className="titleInput" 
            value={title} 
            onChange={(event) => {
              setTitle(event.target.value)
            }}
          />
        </div>
        <div className='bodyAll'>
          <label className="body">내용</label>
          <textarea
            className="bodyInput" 
            rows="20"
            value={body} 
            onChange={(event) => {
              setBody(event.target.value)
            }}
          />
        </div>
        <button
          className="btn"
          onClick={onSubmit}
        >
          Post</button>
      </div>
    </div>
  );
};

제목이 들어가는 text input과 내용이 들어가는 textarea가 있을 때
useState를 이용하여 [title, setTitle], [body, setBody]의
빈 내용의 변수를 만들고 각각의 값은 title과 body 변수에 넣고
실시간으로 바뀌는 값은 onChange로 set변수에 담아주면
set 변수에 담겨져 있는 값이 title과 body 변수에 전달되는 것이다

const onSubmit = () => {
    axios.post('http://localhost:3001/posts', {
      title: title,
      body: body, 
    })
  };

이후 onSubmit이라는 함수를 만들어 axios.post()를 사용하여
title, body 변수로 객체를 만들어주면 post안에 있는 포트 주소로 데이터가 저장된다

{
  "posts": [
    {
      "title": "text",
      "body": "text",
      "id": 1
    },
    {
      "title": "text",
      "body": "text",
      "id": 2
    }
  ]
}

db.json을 확인해보면 이렇게 사용자가 적은 input 내용이
순서대로 저장되는 것을 볼 수 있다

💡 package.json에 서버 추가하기

  "scripts": {
    "start": "react-scripts start",
    "db": "json-server --watch db.json --port 3001",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },

스크립트 부분에 db: json-server --watch db.json를 추가해주면
터미널에 npm run db로 간단하게 서버를 실행할 수 있다


🚩 저장한 데이터 불러오기

import axios from "axios";
import { useState, useEffect } from 'react';

const ListPage = () => {
  const [posts, setPosts] = useState([]);

  const getPosts = () => {
    axios.get('http://localhost:3001/posts').then((res) => {
      setPosts(res.data);
    })
  }
  useEffect(() => {
    getPosts();
  }, []);

  return (
    <div>
      <h1>Blog</h1>
      {posts.map(post => {
        return (
          <div key={post.id}>{post.title}</div>
        );
      })}
    </div>
  );
};

axios.get()을 사용하여 저장한 데이터를 가져온다
get()안에는 서버로 사용하고 있는 로컬주소에 /posts를 적어주는데
/posts는 여러개의 포스트를 가져올 때 사용하며
특정 포스트를 가져올 때는 /posts/(부여된 id)를 적어준다

const getPosts = () => {
    axios.get('http://localhost:3001/posts').then((res) => {
      setPosts(res.data);
    })
  }

axios.get()으로 데이터를 요청한 후 받아온 요청을 사용하기 위해선
then()을 사용해야 하는데 then안에는 함수가 들어가게 된다
이 함수는 요청을 보냈을 때 받아오는 응답의 데이터가 되는 것이다

💡 여기서 문제점

정해진 데이터를 한번만 전송하고 싶어도 응답한 데이터를
실시간으로 전송하기 때문에 무한대로 담겨지게 된다
여기서 useEffect를 사용하게 되면 이 문제를 해결할 수 있다

useEffect(() => {
    getPosts();
  }, []);

useEffect는 함수와 배열을 같이 쓰는게 기본 값이고
get한 함수를 넣어주면 처음에 딱 한번만 실행되게 만드는 명령어이다


🚩 불러온 데이터 화면 출력하기

return (
    <div>
      <h1>Blog</h1>
      {posts.map(post => {
        return (
          <div key={post.id}>{post.title}</div>
        );
      })}
    </div>
  );

db에 담긴 데이터들을 한번에 가져오기 위해 map함수를 이용하는데
key 값을 넣지 않으면 오류가 생기기 때문에 id를 꼭 넣어준다
이후 return으로 db.json에 저장된 title을 div 안으로 불러오면 화면에 출력된다


✒️ 공부하면서...

DB와 비슷한 원리를 가진 json server를 다루게 되면서
데이터베이스의 원리와 연결하는 방법을 알게 되었다
추후 DB를 연결하게 될 때 더 원활하게 연결할 수 있지 않을까 생각된다

profile
디자인에서 프론트엔드 개발까지 하게 된 구름이 집사😺

0개의 댓글