New

리액트에서 MySQL 테이블 연결하여 CRUD 기능 구현하는 로직 예시 코드

lshjju 2026. 1. 15. 12:07

Prompt


리액트 MySQL 연결 CRUD 예시코드


 

MySQL 테이블 생성부터 리액트에서 **Update(수정)**와 Delete(삭제) 기능을 포함한 전체 CRUD 로직을 완성해 보겠습니다.


1. MySQL 테이블 생성 및 샘플 데이터

먼저 MySQL 워크벤치나 터미널에서 아래 쿼리를 실행하여 실습용 테이블을 만듭니다.

SQL
 
-- 데이터베이스 생성 (없을 경우)
CREATE DATABASE my_crud_db;
USE my_crud_db;

-- 테이블 생성
CREATE TABLE items (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    content TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 샘플 데이터 삽입
INSERT INTO items (name, content) VALUES ('첫 번째 할 일', '리액트 공부하기');

2. 전체 CRUD 코드 (백엔드: Node.js)

기존 코드에 **PUT(수정)**과 DELETE(삭제) API를 추가한 전체 모습입니다.

JavaScript
 
// server.js (핵심 부분만 발췌)

// UPDATE: 데이터 수정
app.put('/api/items/:id', (req, res) => {
  const { id } = req.params;
  const { name, content } = req.body;
  const sql = "UPDATE items SET name = ?, content = ? WHERE id = ?";
  
  db.query(sql, [name, content, id], (err, result) => {
    if (err) return res.status(500).json(err);
    res.json({ message: "수정 성공" });
  });
});

// DELETE: 데이터 삭제
app.delete('/api/items/:id', (req, res) => {
  const { id } = req.params;
  const sql = "DELETE FROM items WHERE id = ?";
  
  db.query(sql, [id], (err, result) => {
    if (err) return res.status(500).json(err);
    res.json({ message: "삭제 성공" });
  });
});

3. 전체 CRUD 코드 (프론트엔드: React)

사용자 인터페이스에서 각 기능을 호출하는 방법입니다.

JavaScript
 
import React, { useEffect, useState } from 'react';
import axios from 'axios';

const API_URL = 'http://localhost:5000/api/items';

function App() {
  const [items, setItems] = useState([]);
  const [name, setName] = useState('');
  const [editId, setEditId] = useState(null); // 수정 중인 아이디

  // 데이터 로드 (Read)
  const fetchItems = async () => {
    const res = await axios.get(API_URL);
    setItems(res.data);
  };

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

  // 추가 및 수정 (Create & Update)
  const handleSubmit = async () => {
    if (editId) {
      // 수정 모드
      await axios.put(`${API_URL}/${editId}`, { name, content: '수정됨' });
      setEditId(null);
    } else {
      // 추가 모드
      await axios.post(API_URL, { name, content: '새 내용' });
    }
    setName('');
    fetchItems(); // 목록 새로고침
  };

  // 삭제 (Delete)
  const handleDelete = async (id) => {
    if (window.confirm("정말 삭제하시겠습니까?")) {
      await axios.delete(`${API_URL}/${id}`);
      fetchItems();
    }
  };

  return (
    <div style={{ padding: '20px' }}>
      <h1>React + MySQL CRUD</h1>
      <input 
        value={name} 
        onChange={(e) => setName(e.target.value)} 
        placeholder="항목 이름 입력"
      />
      <button onClick={handleSubmit}>{editId ? '수정 완료' : '추가'}</button>

      <ul>
        {items.map(item => (
          <li key={item.id}>
            {item.name} 
            <button onClick={() => { setEditId(item.id); setName(item.name); }}>수정</button>
            <button onClick={() => handleDelete(item.id)}>삭제</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;

💡 구현 시 주의할 점 (Checklist)

  1. CORS 에러: 백엔드에서 app.use(cors()) 설정을 하지 않으면 리액트에서 데이터를 요청할 때 보안 에러가 발생합니다.
  2. Async/Await: 서버 요청은 비동기 작업이므로 async/await 또는 .then()을 사용하여 응답이 올 때까지 기다려야 데이터가 꼬이지 않습니다.
  3. 환경 변수: 실무에서는 DB 비밀번호를 코드에 직접 쓰지 않고 .env 파일에 보관합니다.