아래는 React + SQLite로 **CRUD(Create / Read / Update / Delete)**를 구현하는 정석적인 구조입니다.
중요한 전제는 React(브라우저)는 SQLite에 직접 접근할 수 없기 때문에 반드시 Backend(API 서버)가 필요하다는 점입니다.


1️⃣ 전체 아키텍처

[ React (Frontend) ]
        |
        | REST API (JSON)
        v
[ Node.js + Express ]
        |
        | sqlite3
        v
[ SQLite (.db 파일) ]

2️⃣ SQLite DB 설계

2.1 DB 파일 생성 (database.db)

CREATE TABLE users (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  name TEXT NOT NULL,
  email TEXT NOT NULL
);

3️⃣ Backend (Node.js + Express + SQLite)

3.1 패키지 설치

npm init -y
npm install express cors sqlite3

3.2 DB 연결 (db.js)

const sqlite3 = require('sqlite3').verbose();

const db = new sqlite3.Database('./database.db', (err) => {
  if (err) console.error(err.message);
  else console.log('SQLite connected');
});

module.exports = db;

3.3 API 서버 (server.js)

const express = require('express');
const cors = require('cors');
const db = require('./db');

const app = express();
app.use(cors());
app.use(express.json());

/* CREATE */
app.post('/users', (req, res) => {
  const { name, email } = req.body;
  db.run(
    'INSERT INTO users (name, email) VALUES (?, ?)',
    [name, email],
    function () {
      res.status(201).json({ id: this.lastID });
    }
  );
});

/* READ */
app.get('/users', (req, res) => {
  db.all('SELECT * FROM users', [], (err, rows) => {
    res.json(rows);
  });
});

/* UPDATE */
app.put('/users/:id', (req, res) => {
  const { name, email } = req.body;
  db.run(
    'UPDATE users SET name=?, email=? WHERE id=?',
    [name, email, req.params.id],
    () => res.sendStatus(200)
  );
});

/* DELETE */
app.delete('/users/:id', (req, res) => {
  db.run(
    'DELETE FROM users WHERE id=?',
    [req.params.id],
    () => res.sendStatus(200)
  );
});

app.listen(4000, () => {
  console.log('API server running on port 4000');
});

4️⃣ Frontend (React)

4.1 프로젝트 생성

npx create-react-app react-sqlite-crud
cd react-sqlite-crud
npm install axios
npm start

4.2 API 유틸 (src/api.js)

import axios from 'axios';

export default axios.create({
  baseURL: 'http://localhost:4000'
});

4.3 CRUD 컴포넌트 (src/UserCrud.js)

import { useEffect, useState } from 'react';
import api from './api';

function UserCrud() {
  const [users, setUsers] = useState([]);
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');

  const loadUsers = async () => {
    const res = await api.get('/users');
    setUsers(res.data);
  };

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

  const createUser = async () => {
    await api.post('/users', { name, email });
    setName('');
    setEmail('');
    loadUsers();
  };

  const deleteUser = async (id) => {
    await api.delete(`/users/${id}`);
    loadUsers();
  };

  return (
    <div>
      <h2>User CRUD</h2>

      <input
        placeholder="Name"
        value={name}
        onChange={e => setName(e.target.value)}
      />
      <input
        placeholder="Email"
        value={email}
        onChange={e => setEmail(e.target.value)}
      />
      <button onClick={createUser}>Add</button>

      <ul>
        {users.map(u => (
          <li key={u.id}>
            {u.name} ({u.email})
            <button onClick={() => deleteUser(u.id)}>Delete</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default UserCrud;

4.4 App.js

import UserCrud from './UserCrud';

function App() {
  return <UserCrud />;
}

export default App;

5️⃣ 실행 순서

  1. SQLite DB 생성
  2. Backend 실행
node server.js
  1. Frontend 실행
npm start

6️⃣ 실무에서 중요한 포인트

  • SQLite는 단일 파일 DB → 동시성 제한 있음
  • WAL 모드 권장
  • PRAGMA journal_mode=WAL;
  • API 서버는 싱글톤 DB 연결 유지
  • 웹 서비스라면 SQLite는 개발/소규모 서비스용

7️⃣ 대안 구조 (중요)

환경권장 방식

웹 서비스 SQLite ❌ → MariaDB / PostgreSQL
로컬 앱 React + Electron + SQLite ✅
서버리스 SQLite ❌

다음 단계로 바로 이어갈 수 있는 주제

  • React + SQLite + Electron (데스크톱 앱)
  • SvelteKit / Next.js에서 SQLite 직접 사용
  • SQLite → MariaDB 마이그레이션 전략
  • REST vs GraphQL CRUD 구조 비교

원하시는 방향을 정확히 말씀해 주시면 그 기준으로 깊게 정리해 드리겠습니다.

728x90

+ Recent posts