React와 Node.js를 사용한 웹 애플리케이션 개발

React와 Node.js를 사용한 웹 애플리케이션(게시판) 개발 강좌(20)

atomicdev 2024. 9. 21. 10:12
728x90

댓글 기능 구현: 댓글 작성 및 조회 API 및 프론트엔드에서 댓글 입력 및 표시

이번 강의에서는 댓글 기능을 구현하여 사용자가 게시글에 댓글을 작성하고, 작성된 댓글을 조회하는 방법을 다룹니다. Node.jsMySQL을 사용해 댓글 관련 API를 구현하고, React에서 댓글 입력과 조회를 처리합니다.

댓글 기능을 구현한 과정


1. 댓글 작성 및 조회 API 구현

1.1 댓글 테이블 생성

먼저 MySQL에서 댓글 데이터를 저장할 comments 테이블을 생성합니다. 각 댓글은 게시글과 연결되며, 댓글 작성자의 이름과 댓글 내용이 저장됩니다.

CREATE TABLE comments (
  id INT AUTO_INCREMENT PRIMARY KEY,
  post_id INT,              -- 댓글이 속한 게시글 ID
  username VARCHAR(100),    -- 댓글 작성자
  content TEXT,             -- 댓글 내용
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE
);

1.2 댓글 작성 API

POST 요청을 통해 특정 게시글에 댓글을 작성하는 API를 구현합니다.

// server.js
app.post('/api/posts/:postId/comments', (req, res) => {
  const { postId } = req.params;
  const { username, content } = req.body;

  const query = 'INSERT INTO comments (post_id, username, content) VALUES (?, ?, ?)';
  db.query(query, [postId, username, content], (err, result) => {
    if (err) {
      return res.status(500).send('Error creating comment');
    }
    res.status(201).send('Comment added successfully');
  });
});

1.3 댓글 조회 API

특정 게시글에 작성된 댓글을 조회하는 GET 요청 API를 구현합니다.

app.get('/api/posts/:postId/comments', (req, res) => {
  const { postId } = req.params;

  const query = 'SELECT * FROM comments WHERE post_id = ? ORDER BY created_at DESC';
  db.query(query, [postId], (err, results) => {
    if (err) {
      return res.status(500).send('Error fetching comments');
    }
    res.json(results);
  });
});

2. 프론트엔드에서 댓글 입력 및 조회 기능 구현

2.1 댓글 입력 폼

사용자가 댓글을 입력할 수 있는 폼을 구현하고, axios를 사용해 댓글 데이터를 서버로 전송합니다.

// src/components/CommentForm.js
import React, { useState } from 'react';
import axios from 'axios';

function CommentForm({ postId, onCommentAdded }) {
  const [username, setUsername] = useState('');
  const [content, setContent] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();

    const newComment = {
      username,
      content,
    };

    axios.post(`/api/posts/${postId}/comments`, newComment)
      .then(() => {
        alert('댓글이 작성되었습니다.');
        setUsername('');
        setContent('');
        onCommentAdded(); // 새로운 댓글 추가 후 리스트 업데이트
      })
      .catch((error) => {
        console.error('Error creating comment:', error);
      });
  };

  return (
    <form onSubmit={handleSubmit}>
      <h3>댓글 작성</h3>
      <div>
        <label>작성자</label>
        <input
          type="text"
          value={username}
          onChange={(e) => setUsername(e.target.value)}
          required
        />
      </div>
      <div>
        <label>내용</label>
        <textarea
          value={content}
          onChange={(e) => setContent(e.target.value)}
          required
        ></textarea>
      </div>
      <button type="submit">댓글 작성</button>
    </form>
  );
}

export default CommentForm;

2.2 댓글 목록 표시

서버에서 댓글 데이터를 불러와 화면에 렌더링합니다. useEffect를 사용해 컴포넌트가 렌더링될 때 댓글 데이터를 불러옵니다.

// src/components/CommentList.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';

function CommentList({ postId }) {
  const [comments, setComments] = useState([]);

  // 댓글 목록 불러오기
  useEffect(() => {
    axios.get(`/api/posts/${postId}/comments`)
      .then(response => setComments(response.data))
      .catch(error => console.error('Error fetching comments:', error));
  }, [postId]);

  return (
    <div>
      <h3>댓글 목록</h3>
      {comments.length > 0 ? (
        <ul>
          {comments.map(comment => (
            <li key={comment.id}>
              <strong>{comment.username}</strong>: {comment.content}
            </li>
          ))}
        </ul>
      ) : (
        <p>댓글이 없습니다.</p>
      )}
    </div>
  );
}

export default CommentList;

2.3 댓글 작성 후 목록 업데이트

댓글 작성 후, 댓글 목록이 자동으로 업데이트되도록 onCommentAdded 콜백 함수를 CommentForm 컴포넌트에 전달합니다.

// src/components/PostDetail.js
import React, { useState } from 'react';
import CommentForm from './CommentForm';
import CommentList from './CommentList';

function PostDetail({ post }) {
  const [commentsUpdated, setCommentsUpdated] = useState(false);

  const handleCommentAdded = () => {
    setCommentsUpdated(!commentsUpdated); // 댓글 추가 시 상태 변경
  };

  return (
    <div>
      <h2>{post.title}</h2>
      <p>{post.content}</p>
      <CommentForm postId={post.id} onCommentAdded={handleCommentAdded} />
      <CommentList postId={post.id} key={commentsUpdated} />
    </div>
  );
}

export default PostDetail;

3. 전체 흐름

  1. 댓글 작성: 사용자가 댓글을 작성하고 POST 요청을 통해 서버에 전송합니다.
  2. 댓글 조회: 서버에서 해당 게시글의 댓글을 불러와 GET 요청으로 클라이언트에 전달합니다.
  3. 목록 업데이트: 댓글 작성 후, 새로운 댓글이 목록에 반영되도록 상태를 업데이트합니다.

결론

이번 강의에서는 댓글 기능을 구현하여 게시글에 댓글을 작성하고 조회하는 방법을 배웠습니다. React에서 입력 폼과 목록 컴포넌트를 사용하여 프론트엔드를 구성하고, Node.jsMySQL을 사용해 서버에서 댓글 데이터를 처리하는 방법을 다루었습니다.

728x90