4 글 보임 - 1 에서 4 까지 (총 4 중에서)
-
글쓴이글
-
2023년 9월 20일 05:29 #98605
우치하마다라참가자안녕하세요. 선생님 좋아요 체크, 좋아요 취소 둘의 기능을 구현하였는데 문제가 있습니다. 기능은 이렇습니다. 1.상세페이지에 들어와있을때 좋아요가 눌러져 있다면 채워져있는하트, 아니면 빈하트 (이 기능은 문제가 없습니다.) 2. 좋아요 체크 3. 좋아요 취소(좋아요 체크되어있을 시 취소됨) 4. 좋아요 누른 유저 목록 보여주기 (누른 유저가 없으면 가려짐) 여튼... 문제는 이렇습니다.
상세 페이지에서 좋아요 체크, 취소를 하면 잘되지만(다른 링크로 이동안했을 경우) Link 에 걸려있는 홈이라든지, list 페이지로 이동한뒤 다시 좋아요를 눌렀거나 취소를 했던 페이지(좋아요 눌렀거나 취소한 페이지)로 가면 변화가 없습니다. (새로고침을 하면 정상반영이 됩니다.) 서버에서 결과값을 보내줘서 그값을 state로 변경해주는 방식입니다. 서버에서는 바뀐값이 정상으로 나옵니다
그러나 상세페이지 좋아요 버튼 기능 페이지에서는 이렇게 나옵니다. 좋아요 체크를 눌렀을 시 나오는 콘솔 화면입니다. 분명 서버에서 받은 값 result 를 출력하면 잘나옵니다만 state 들을 출력해보면 이런식으로 나오네요...
<--- 상세페이지 ---> import { connectDB } from "@/util/database" import { MongoClient, ObjectId } from "mongodb" import Comment from './Comment' import PostLike from './PostLike' import { getServerSession } from "next-auth" import { authOptions } from "@/pages/api/auth/[...nextauth]" export default async function Detail(props){ const client = await connectDB const db = client.db('forum') let result = await db.collection('post').findOne({_id : new ObjectId(props.params.id)}) let session = await getServerSession(authOptions) let elementExis = null console.log(session.user) if(session){ if(result.likeUser.includes(session.user.email)){ // 여기서 중복체크를 하여 좋아요 눌렀는지 여부 확인 elementExis = true } else { elementExis = false } } else { console.log('비로그인') } return( <div> <h4>상세페이지</h4> <h4>{result.title}</h4> <p>{result.content}</p> <span>작성자 {result.name} - {result.author}</span> <PostLike result={result} name={result.name} _id={result._id} likeUser={result.likeUser} postLikeCount={result.postLikeCount} session={session} elementExis={elementExis}/> <Comment _id={result._id} /> </div> ) } <--- 상세페이지 좋아요 버튼 기능 페이지 ---> 'use client' import { useEffect, useState } from "react" export default function PostLike(props){ let [heart, setHeart] = useState('🤍') let [auto, setAuto] = useState(props.elementExis) useEffect(()=>{ if(auto === null || auto === false){ console.log('좋아요 안눌러져 있을 때') setHeart('🤍') } else if (auto === true){ console.log('좋아요 눌러져 있을 때') setHeart('❤️') } },[]) let [likeUserList, setLikeUserList] = useState(props.likeUser) let [likeCount, setLikeCount] = useState(props.postLikeCount) let [trg, setTrg] = useState(false) // let [err, setErr] = useState(true) let res = null return( <div> <div> {likeCount < 1 ? null : <p>{likeCount} 명이 좋아합니다.</p>} <span>좋아요</span> <button onClick={(e)=>{ { if(auto === null || auto === false){ // 좋아요 안눌러저 있을 때 console.log('좋아요 안눌러져 있을 때') fetch('/api/like/likePlus',{ method : "POST", body : JSON.stringify({likeCount : likeCount, _id : props._id, name : props.name}) }).then((response)=>{ if(response.status === 200){ res = true return response.json() } else { res = false return response.json() } }).then((result)=>{ if(res === true){ // 로그인 세션 존재 하면 setAuto(true) setHeart(result[0]) setLikeUserList(result[1]) setLikeCount(result[2]) console.log('좋아요 체크') } else { // 로그인 세션 존재 하지 않으면 setErr('권한이 없습니다.') } }).catch((error)=>{ console.log(error) }) } else if(auto === true){ // 좋아요 눌러저 있을 떄 console.log('좋아요 눌러져 있을 때') fetch('/api/like/likeMinus', { method : "POST", body : JSON.stringify({likeCount : likeCount, _id : props._id, name : props.name}) }).then((response)=>{ if(response.status === 200){ res = true return response.json() } else { res = false return response.json() } }).then((result)=>{ if(res === true){ setAuto(false) setHeart(result[0]) setLikeUserList(result[1]) setLikeCount(result[2]) console.log('좋아요 취소') } else { setErr('권한이 없습니다.') } }).catch((error)=>{ console.log(error) }) } } }}>{heart}</button> {likeCount < 1 ? null : <button onClick={()=>{ setTrg(!trg) }}>좋아요 목록</button>} {trg === false ? null : <ListOne likeUserList={likeUserList}/>} {/* {err === false ? null : <ErrPopup err={err} /> } */} </div> <button onClick={()=>{ }}>근황버튼</button> </div> ) } function ListOne(props){ return( <div>
-
<li style="list-style-type: none;">
- { props.likeUserList.map((a, i)=>{ return( <li key={i}>{a}
) }) }
</div> ) } <--- 좋아요 체크 서버 api --->
import { connectDB } from "@/util/database" import { getServerSession } from "next-auth" import { authOptions } from "../auth/[...nextauth]" import { ObjectId } from "mongodb"
export default async function handler(req, res){ let session = await getServerSession(req, res, authOptions) if(req.method === 'POST'){ if(session){ req.body = JSON.parse(req.body) let client = await connectDB let db = client.db('forum') let result = await db.collection('user_cred').findOne({email : session.user.email}) let save = { user : session.user.name, // 좋아요 누른 유저의 이름 userLike_id : new ObjectId(result._id), // 좋아요 누른 유저의 _id postUser : req.body.name, // 해당 글 작성자 이름 postLike_id : new ObjectId(req.body._id) // 해당 글의 _id } console.log(req.body) let result2 = await db.collection('post').findOne({_id : new ObjectId(save.postLike_id)}) let arrUser = {likeUser : session.user.email} // 현재 좋아요 누른 유저의 이메일 정보 let countPlus = {postLikeCount : 1} // 1증가 try{ await db.collection('post').updateOne({_id : new ObjectId(result2._id)}, {$push : arrUser}) await db.collection('post').updateOne({_id : new ObjectId(result2._id)}, {$inc : countPlus}) await db.collection('postlike').insertOne(save) let countRe = await db.collection('post').findOne({_id : new ObjectId(result2._id)}) // 좋아요 수 출력 console.log(countRe) return res.status(200).json(['❤️', countRe.likeUser, countRe.postLikeCount]) } catch{ return res.status(500).json('서버 오류') } } else { return res.status(400).json('권한이 없습니다.') } } else { return res.status(400).json('잘못된 접근입니다.') } } <--- 좋아요 취소 서버 api --->
import { connectDB } from "@/util/database"; import { authOptions } from "../auth/[...nextauth]"; import { getServerSession } from "next-auth"; import { ObjectId } from "mongodb";
export default async function(req, res){
if(req.method === "POST"){ // POST 로 받았을 때 let session = await getServerSession(req, res, authOptions) // 현재 로그인한 세션 if(session){ // 세션이 존재하는가 ? req.body = JSON.parse(req.body) let client = await connectDB let db = client.db('forum') let result = await db.collection('user_cred').findOne({email : session.user.email}) let minusSave = { user : session.user.name, // 좋아요 누른 유저의 이름 userLike_id : new ObjectId(result._id), // 좋아요 누른 유저의 _id postUser : req.body.name, // 해당 글 작성자 이름 postLike_id : new ObjectId(req.body._id) // 해당 글의 _id } let result2 = await db.collection('post').findOne({_id : new ObjectId(minusSave.postLike_id)}) let arrUser = {likeUser : session.user.email} // 현재 좋아요 누른 유저의 이메일 정보 let countPlus = {postLikeCount : -1} // 1감소 try { await db.collection('post').updateOne({_id : new ObjectId(result2._id)}, {$pull : arrUser}) await db.collection('post').updateOne({_id : new ObjectId(result2._id)}, {$inc : countPlus}) await db.collection('postlike').deleteOne(minusSave) let countRe = await db.collection('post').findOne({_id : new ObjectId(result2._id)}) // 좋아요 수 출력 console.log(countRe) return res.status(200).json(['🤍',countRe.likeUser, countRe.postLikeCount]) } catch { return res.status(500).json('실패') } } } else { // POST 외에 다른 요청으로 받았을 때 실패 return res.status(400).json('잘못된 접근입니다.') } }
2023년 9월 20일 09:29 #98617
codingapple키 마스터props를 다시 useState에 넣어서 쓰면 안되고 그냥 씁시다 근데 좋아요처리하는 서버기능에서 이미 이메일이 거기 array안에 있으면 $push 하지말라는 로직도 추가해야할듯요
-
글쓴이글
4 글 보임 - 1 에서 4 까지 (총 4 중에서)
- 답변은 로그인 후 가능합니다.