본문 바로가기
React

[React] 리액트 댓글 좋아요 구현하기

by dev수니 2021. 12. 23.
반응형

아래는 먼저 페이지의 js이다.

 

frontend/src/user/pages/detailPage.jsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import React, { useEffect, useState } from "react";
import { Link, useParams } from "react-router-dom";
 
import ReplyLike from ../components/replyLike;
 
const UploadPage = () => {
    const param = window.location.search.split('=')[1]  // memberIdx (현재 로그인한 사람의 idx)
    const {idx} = useParams();  // postIdx(게시물의 idx)
    const [replyArr, setReplyArr] = useState([]);    // 댓글 배열 저장할 useState
 
    useEffect(async () => {
        // 게시물 디테일 가져오기
        const list = await axios.get("http://localhost:3001/post/detail?postIdx="+idx);
        console.log(list);
 
        // 게시물 정보 입력
        setReplyArr(list.data[2]);
    }, []);
 
    // 전체 DOM
    return (
        {
            replyArr.length !== 0 ?
                replyArr.map((data) => {
                    return (
                        <ReplyLike className="like_box" replyIdx={data.idx} memberIdx={param}/>
                    )
                });
            : <div className="reply_warn">등록된 댓글이 없습니다. 댓글을 등록해보세요.</div>
        }
    )
cs

axios 로 데려온 data를 state 에 담고 map으로 돌려 댓글을 출력해주었다.

그리고 ReplyLike 컴포넌트에 해당 댓글의 idx와 멤버 idx를 props로 전달해주었다. 

 

 

 

다음은 좋아요 버튼 컴포넌트이다.

frontend/src/user/components/replyLike.jsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import React, {useEffect, useRef, useState} from "react";
import axios from "axios";
 
const ReplyLike = ({replyIdx, memberIdx})=>{
    const [isLike, setIsLike] = useState('0');
 
    useEffect(async () => {
        const getAxios = await axios.get(`http://localhost:3001/reply/like/exist?replyIdx=${replyIdx}&memberIdx=${memberIdx}`);
        console.log(getAxios);
        setIsLike(getAxios.data[0].success);
    }, [isLike]);
 
    const handleClick = async ()=>{
        axios.get(`http://localhost:3001/reply/like?replyIdx=${replyIdx}&memberIdx=${memberIdx}`).then((res)=>{
            console.log(res.data);
            res.data ? setIsLike('1') : setIsLike('0');
        });
    }
 
    return(
        isLike===1 ? 
            <div className="like_box">
                <button type="button" className="like_btn">
                    <img className="like_img" src="/img/heart.png" alt="좋아요비활성화" onClick={handleClick}/>
                </button>
            </div>
        :
        <div className="like_box">
            <button type="button" className="like_btn">
                <img className="like_img" src="/img/smile.png" alt="좋아요활성화" onClick={handleClick}/>
            </button>
        </div>
    )
}
 
export default ReplyLike;
cs

먼저 페이지가 로드되자마자 해당 댓글의 좋아요를 여부를 확인해준다. false는 0 true 1이다.

이를 isLike에 저장한다.

 

그리고 DOM에서 isLIke===0 ? 좋아요안했을경우 : 좋아요했을경우

로 바꾼다.

그리고 axios로 좋아요

 

 

다음은 백엔드 node.js 부분이다.

backend/routes/post.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
const express = require('express');
const mysql = require('mysql');
const config = require('../config/config.json');
const bodyParser = require('body-parser');
const fs = require('fs');
const multer = require('multer');
const pool = mysql.createPool(config);
 
const router = express.Router()
router.use(bodyParser.urlencoded({ extended: false }))
 
// 게시글 디테일
router.route('/post/detail').get((req, res) => {
    const postIdx = req.query.postIdx;
    if (pool) {
        postDetail(postIdx, (err, result) => {
            if (err) {
                res.writeHead('200', { 'content-type''text/html; charset=utf8' });
                res.write('<h2>메인데이터 출력 실패 </h2>');
                res.write('<p>데이터가 안나옵니다.</p>')
                res.end();
            } else {
                res.send(result);
            }
        })
    }
})
 
// 게시글 디테일
const postDetail = function(postIdx, callback){
    pool.getConnection((err, conn) => {
        if (err) {
            console.log(err);
        } else {
            const sql1 = 'select p.content, p.createdAt, m.email, m.name, m.img from post as p join member as m on p.memberIdx = m.idx where p.idx = ?;';
            const sql1s = mysql.format(sql1, postIdx)
 
            const sql2 = 'select imgName from img where postIdx = ?;';
            const sql2s = mysql.format(sql2, postIdx);
 
            const sql3 = 'select r.content, m.name, m.email, m.img, r.memberIdx, r.idx,r.groupIdx, r.depth, r.createdAt from reply as r join member as m on r.memberIdx = m.idx where postIdx = ? order by groupIdx asc, groupNum asc;';
            const sql3s = mysql.format(sql3, postIdx);
 
            conn.query(sql1s + sql2s + sql3s, (err, result) => {
                conn.release();
                if (err) {
                    callback(err, null);
                    return;
                } else {
                    callback(null, result);
                }
            });
        }
    });
}
 
cs

게시글 디테일에서 댓글 arr 가져와서 출력한다.

 

 

 

backend/routes/reply.js

다음은 댓글 좋아요 부분

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// 댓글 좋아요 여부
router.route('/reply/like/exist').get((req, res) => {
    const replyIdx = req.query.replyIdx;
    const memberIdx = req.query.memberIdx;
 
    if (pool) {
        replyLikeExist(replyIdx, memberIdx, (err, result) => {
            if (err) {
                res.writeHead('201', { 'content-type''text/html; charset=utf8' });
                res.write('<h2>메인데이터 출력 실패 </h2>');
                res.write('<p>데이터가 안나옵니다.</p>')
                res.end();
            } else {
                res.send(result);
            }
        });
    }
})
 
// 댓글 좋아요 여부
const replyLikeExist = function (replyIdx, memberIdx, callback) {
    pool.getConnection((err, conn) => {
        if (err) {
            console.log(err);
        } else {
            conn.query('select exists (select idx from reply_like where replyIdx = ? and memberIdx = ? limit 1) as success;', [replyIdx, memberIdx], (err, result) => {
 
                conn.release();
                if (err) {
                    callback(err, null);
                    return;
                } else {
                    callback(null, result);
                }
            })
        }
    });
}
 
 
// 댓글 좋아요
router.route('/reply/like').get((req, res) => {
    const replyIdx = req.query.replyIdx;
    const memberIdx = req.query.memberIdx;
 
    if (pool) {
        replyLike(replyIdx, memberIdx, (err, result) => {
            if (err) {
                res.writeHead('201', { 'content-type''text/html; charset=utf8' });
                res.write('<h2>메인데이터 출력 실패 </h2>');
                res.write('<p>데이터가 안나옵니다.</p>')
                res.end();
            } else {
                res.send(result);
            }
        });
    }
})
// 댓글 좋아요
const replyLike = function (replyIdx, memberIdx, callback) {
    pool.getConnection((err, conn) => {
        if (err) {
            console.log(err);
        } else {
            conn.query('select exists (select idx from reply_like where replyIdx = ? and memberIdx = ? limit 1) as success;', [replyIdx, memberIdx], (err, result) => {
                if (result[0].success == 1) {
                    conn.query('delete from reply_like where replyIdx = ? and memberIdx = ?', [replyIdx, memberIdx]);
                } else {
                    conn.query('insert into reply_like(replyIdx, memberIdx) values(?, ?)', [replyIdx, memberIdx]);
                }
                conn.release();
                if (err) {
                    callback(err, null);
                    return;
                } else {
                    callback(nulltrue);
                }
            })
        }
    });
}
 
cs

reply 컴포넌트에서 좋아요 여부 확인할 수 있고 좋아요 취소, 등록 할 수 있다.

 

반응형

'React' 카테고리의 다른 글

[React Query] React query 뿌수기  (0) 2024.04.09
[React] 렌더링 최적화하는 방법  (0) 2022.03.10
[React] CORS 에러 (OPTIONS 요청 발생)  (0) 2021.12.24

댓글