MySQL

React, MySQL 10일차 (댓글 작성자 화면에 표시하기)

수연 (Suyeon) 2023. 10. 24. 23:12
반응형

PedroTech님의 풀스택 강의 10일 차를 참고했습니다.

 

📌 Comments Table 수정하기

// ./server/models/Comments.js

module.exports = (sequelize, DataTypes) => {
  const Comments = sequelize.define("Comments", {
    commentBody: {
      type: DataTypes.STRING,
      allowNull: false,
    },

    username: {
      type: DataTypes.STRING,
      allowNull: false,
    },
  });

  return Comments;
};
Comments 테이블에 username 필드를 추가해서 댓글 작성자 이름을 저장할 수 있게 수정합니다.

 

 

 

📌 사용자 ID 저장하기

// ./server/middlewares/AuthMiddleware.js

const { verify } = require("jsonwebtoken");

const validateTocken = (req, res, next) => {
  const accessTocken = req.header("accessTocken");

  if (!accessTocken) {...
  }

  try {
    const validTocken = verify(accessTocken, "importantsecret");
    // req.user에 값을 저장합니다.
    req.user = validTocken;

    if (validTocken) {...
    }
  } catch (err) {...
  }
};

module.exports = { validateTocken };
// ./server/routers/Comments.js

const express = require("express");
const router = express.Router();
const { Comments } = require("../models");
const { validateTocken } = require("../middlewares/AuthMiddleware");

router.get("/:postId", async (req, res) => {...
});

router.post("/", validateTocken, async (req, res) => {
  const comment = req.body;
  
  // req.user에 저장된 값 중 username을 가져옵니다.
  const username = req.user.username;
  
  comment.username = username;

  await Comments.create(comment);
  res.json(comment);
});

module.exports = router;
AuthMiddleware.js 코드 해석
1. req.user: 사용자의 로그인 값을 req.user 안에 저장합니다.

Comments.js 코드 해석
1. req.user.username: AuthMiddleware에서 저장된 req.user에서 사용자 ID만 가져옵니다.
2. comment.username: Comments 테이블에는 username이라는 필드가 있어서 이렇게 사용해서 username에 맞는 값이 입력되도록 했습니다.

 

 

 

📌 사용자 ID 가져오기

// ./client/pages/Post.js

import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import axios from "axios";

function Post() {
  let { id } = useParams();
  const [postObject, setPostObject] = useState({});
  const [comments, setComments] = useState([]);
  const [newComment, setNewComment] = useState("");

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

  const addComment = () => {
    axios
      .post(
        "http://localhost:3001/comments",
        {
          commentBody: newComment,
          PostId: id,
        },
        {
          headers: {
            // sesstionStorage.getItem("변수명")
            accessTocken: localStorage.getItem("accessTocken"),
          },
        }
      )
      .then((response) => {
        if (response.data.error) {
          alert(response.data.error);
        } else {
          const commentToAdd = {
            commentBody: newComment,
            
            // 사용자 ID 값을 저장합니다.
            username: response.data.username,
          };
          setComments([...comments, commentToAdd]);
          setNewComment("");
        }
      });
  };

  return (
    <div className="postPage">
      <div className="leftSide">...
      </div>
      <div className="rightSide">
        <div className="addCommentContainer">...
        </div>
        <div className="listOfComments">
          {comments.map((comment, key) => {
            return (
              <div key={key} className="comment">
                <span>{comment.commentBody}</span>
                <label>Username: {comment.username}</label>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

export default Post;
axios 코드 해석
1. response.data.username
: username(사용자 ID)을 가져옵니다.
2. username: commentToAdd 안에 따로 key값을 만들어 화면에 표시될 수 있도록 저장했습니다.

return 코드 해석
1. comment.username
: comment 안에 key값인 username으로 value값인 사용자 ID를 반환해 줍니다.

 

 

 

📌 로그인하면 결과 전달하기

const express = require("express");
const router = express.Router();
const { Users } = require("../models");
const bcrypt = require("bcrypt");
const { sign } = require("jsonwebtoken");
const { validateTocken } = require("../middlewares/AuthMiddleware");

router.post("/", async (req, res) => {...
});

router.post("/login", async (req, res) => {...
});

router.get("/auth", validateTocken, (req, res) => {
  res.json(req.user);
});

module.exports = router;
router.get("/auth") 코드 해석
1. router.get("/auth")
: http://localhost:3001/auth/auth를 호출하면 활성화되는 코드입니다.
2. res.json(req.user)
: AuthMiddleware에서 저장했던 것을 json 형식으로 반환해 줍니다.

 

 

 

📌 로그인했을 때 Login, Registration 숨기기 + 화면에 바로 적용하기

import { AuthContext } from "./helpers/AuthContext";
import { useEffect, useState } from "react";
import axios from "axios";

function App() {
  const [authState, setAuthState] = useState(false);

  useEffect(() => {
    axios
      .get("http://localhost:3001/auth/auth", {
        headers: { accessTocken: localStorage.getItem("accessTocken") },
      })
      .then((response) => {
        if (response.data.error) {
          setAuthState(false);
        } else {
          setAuthState(true);
        }
      });
  }, []);

  return (
    <div className="App">
      <AuthContext.Provider value={{ authState, setAuthState }}>
        <BrowserRouter>
          <div className="nav">
            <Link to="/" className="link">
              Home Page
            </Link>
            <Link to="/createpost" className="link">
              Create A Post
            </Link>

            {!authState && (
              <>
                <Link to="/login" className="link">
                  Login
                </Link>
                <Link to="/registration" className="link">
                  Registration
                </Link>
              </>
            )}
          </div>

          <Routes>...
          </Routes>
        </BrowserRouter>
      </AuthContext.Provider>
    </div>
  );
}

export default App;
변수 설명
1. authState: 로그인의 상태를 저장하는 변수입니다.
                      (로그인⭕: true, 로그인❌: false)
2. setAuthState: authState의 값을 변경해 주는 함수입니다.


axios 코드 해석
1. headers
: 데이터를 저장하는 부분입니다.
                    (jsonwebtocken은 데이터를 header에 저장합니다.)
2. localStorage.getItem("변수명"): localStorage에 저장된 데이터를 가져옵니다.
3. setAuthState(false), setAuthState(true): 로그인을 실패(response.data.error)했을 경우 authState에 false를 저장하고, 로그인을 성공했을 경우 true를 저장합니다.


return 코드 해석
1. !authState && <~>
: authState가 true일 때만 화면에 <> 안에 있는 태그들이 보이게 됩니다.
2. AuthContext.Provider: props를 전달할 때 필요한 컴포넌트에만 값을 전달할 수 있도록 도와주는 역할을 합니다.
    value의 값에 정의된 것이 변경될 때마다 이 안에서 사용하고 있는 값도 같이 변경됩니다.
    (값이 변경되면 자동으로 새로고침이 되어서 변경된 사항을 화면에 즉시 보여줍니다.)

 

 

 

📌 결과

로그인

로그인 하기 전 Login 네비게이션이 보여지는 화면

 

로그인 했을 때 Login 네비게이션이 사라지는 화면

 

 

댓글 작성

댓글을 작성하면 사용자 이름도 같이 보이는 화면

 

 

 

📌 느낀 점

지금 팀프로젝트를 준비하고 있는데 거기서도 댓글 다는 기능이 있는데 이 강의를 통해 댓글을 작성했을 때 내용과 사용자 이름을 어떤 방식으로 보이게 하면 되는지를 배울 수 있어서 정말 감사했습니다!

꾸준히 강의를 들을 수 있도록 노력하고 있는데 강의마다 제가 프로젝트에서 직접 해야 할 것들을 미리 배우는 것 같아 부담감이 조금 내려가면서 잘 헤쳐나갈 수 있을 것 같다는 믿음이 생기고 있는 중입니다.

다음 강의에서는 어떤 부분을 배우게 될지 기대되네요.😊

728x90