묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
카카오맵 이 출력이 안되요
window.kakao에 underfined로 나와요...
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
retweet 관련 질문이 있습니다.
다름이 아니라 리트윗빼고는 문제가 없습니다.하지만 리트윗을 하게 되면 데이터베이스에 userid가 null로 들어가면서 게시글을 불러올때 userid가 없기때문에 오류가 나는 것으로 보입니다... 해결해보려고 노력하는 중입니다만 어디가 문제인지 잘 모르겠습니다.const express = require("express"); const multer = require("multer"); const path = require("path"); const fs = require("fs"); const { Post, Image, Comment, User, Hashtag } = require("../models"); const { isLoggedIn } = require("./middlewares"); const router = express.Router(); try { fs.accessSync("uploads"); } catch (error) { console.log("uploads폴더가 없으므로 생성합니다."); fs.mkdirSync("uploads"); } const upload = multer({ storage: multer.diskStorage({ //어디에 저장할지 diskStorage => 하드디스크에 저장 destination(req, file, done) { done(null, "uploads"); }, filename(req, file, done) { // 제로초.png const ext = path.extname(file.originalname); // 확장자 추출(.png) const basename = path.basename(file.originalname, ext); // 제로초 done(null, basename + "_" + new Date().getTime() + ext); // 제로초15184712891.png }, }), limits: { fileSize: 20 * 1024 * 1024 }, // 20MB }); router.post("/", isLoggedIn, upload.none(), async (req, res, next) => { // 보기에는 "/"로 되어있지만 실제로는 "/post"로 되어있다. try { const hashtags = req.body.content.match(/#[^\s#]+/g); //hashtag 정규식 const post = await Post.create({ content: req.body.content, UserId: req.user.id, }); if (hashtags) { const result = await Promise.all( hashtags.map( (tag) => Hashtag.findOrCreate({ //있으면 가져오고 없으면 추가해라 where: { name: tag.slice(1).toLowerCase() }, }) //[[노드, true], [리액트, true]] 이런식으로 나옴 //slice는 글자만 떼기 위해 ex ) #react인 경우 react만 꺼냄 ) ); await post.addHashtags(result.map((v) => v[0])); //위에 같은 형식이기 때문에 0번째만 꺼내야함 } if (req.body.image) { if (Array.isArray(req.body.image)) { //여러개의 이미지를 올린 경우 const images = await Promise.all( req.body.image.map((image) => Image.create({ src: image })) ); await post.addImages(images); } else { const image = await Image.create({ src: req.body.image }); await post.addImages(image); } } const fullPost = await Post.findOne({ where: { id: post.id }, include: [ { model: Image, }, { model: Comment, include: [ { model: User, //댓글 작성자 attributes: ["id", "nickname"], }, ], }, { model: User, //게시글 작성자 attributes: ["id", "nickname"], }, { model: User, //좋아요 누른 사람 as: "Likers", attributes: ["id"], }, ], }); res.status(201).json(fullPost); //다시 프론트로 돌려주기 } catch (error) { console.error(error); next(error); } }); router.post("/:postId/comment", isLoggedIn, async (req, res, next) => { //:postId는 동적으로 바뀐다. //POST /post/comment // 보기에는 "/"로 되어있지만 실제로는 "/post"로 되어있다. try { const post = await Post.findOne({ //이 게시물이 진짜 있는지. where: { id: req.params.postId }, }); if (!post) { return res.status(403).send("존재하지 않는 게시글입니다."); } const comment = await Comment.create({ content: req.body.content, PostId: parseInt(req.params.postId, 10), //문자열로 넘어가기 때문에 int형으로 바꿔줘야한다. UserId: req.user.id, }); const fullComment = await Comment.findOne({ where: { id: comment.id }, include: [ { model: User, attributes: ["id", "nickname"], }, ], }); res.status(201).json(fullComment); } catch (error) { console.error(error); next(error); } }); router.patch("/:postId/like", isLoggedIn, async (req, res, next) => { //PATCH /post/1/like\ try { const post = await Post.findOne({ where: { id: req.params.postId } }); if (!post) { return res.status(403).send("게시글이 존재하지 않습니다."); } await post.addLikers(req.user.id); res.json({ PostId: post.id, UserId: req.user.id }); } catch (error) { console.error(error); next(error); } }); router.delete("/:postId/like", isLoggedIn, async (req, res, next) => { //DELETE /post/1/like try { const post = await Post.findOne({ where: { id: req.params.postId } }); if (!post) { return res.status(403).send("게시글이 존재하지 않습니다."); } await post.removeLikers(req.user.id); res.json({ PostId: post.id, UserId: req.user.id }); } catch (error) { console.error(error); next(error); } }); router.delete("/:postId", isLoggedIn, async (req, res, next) => { // DELETE /post/10 try { await Post.destroy({ where: { id: req.params.postId, UserId: req.user.id, }, }); res.status(200).json({ PostId: parseInt(req.params.postId, 10) }); } catch (error) { console.error(error); next(error); } }); router.post( "/images", isLoggedIn, upload.array("image"), //PostForm.js에서input에 올린 이미지가 배열로 들어감 (이미지를 여러장 올릴 수 있게 하기 위해서) async (req, res, next) => { // POST /post/images/ //이곳은 이미지 업로드 후 실행되는 부분, 업로드는 위에 upload에서 이미 다 올라감 console.log(req.files); res.json(req.files.map((v) => v.filename)); //프론트로 보내줌 } ); router.post("/:postId/retweet", isLoggedIn, async (req, res, next) => { // POST /post/1/retweet try { const post = await Post.findOne({ where: { id: req.params.postId }, include: [ { model: Post, as: "Retweet", }, ], }); if (!post) { return res.status(403).send("존재하지 않는 게시글입니다."); } if ( req.user.id === post.UserId || (post.Retweet && post.Retweet.UserId === req.user.id) ) { return res.status(403).send("자신의 글은 리트윗할 수 없습니다."); } const retweetTargetId = post.RetweetId || post.id; const exPost = await Post.findOne({ where: { UserId: req.user.id, RetweetId: retweetTargetId, }, }); if (exPost) { return res.status(403).send("이미 리트윗했습니다."); } const retweet = await Post.create({ UserId: req.user.id, RetweetId: retweetTargetId, content: "retweet", }); const retweetWithPrevPost = await Post.findOne({ where: { id: retweet.id }, include: [ { model: Post, as: "Retweet", include: [ { model: User, attributes: ["id", "nickname"], }, { model: Image, }, ], }, { model: User, attributes: ["id", "nickname"], }, { model: Image, }, { model: Comment, include: [ { model: User, attributes: ["id", "nickname"], }, ], }, ], }); res.status(201).json(retweetWithPrevPost); } catch (error) { console.error(error); next(error); } }); module.exports = router; //node에서는 import와 export defau lt를 사용하지 않고 require를 사용한다. //리트윗 case RETWEET_REQUEST: draft.retweetDone = false; draft.retweetLoading = true; draft.retweetError = null; break; case RETWEET_SUCCESS: draft.retweetLoading = false; draft.retweetDone = true; draft.mainPosts.unshift(action.data); break; case RETWEET_FAILURE: draft.retweetLoading = false; draft.retweetError = action.error; break; default: break; } }); export default reducer;//리트윗 function retweetAPI(data) { return axios.post(`/post/${data}/retweet`); //data는 formdata다 } function* retweet(action) { try { const result = yield call(retweetAPI, action.data); yield put({ type: RETWEET_SUCCESS, data: result.data, }); } catch (err) { console.error(err); yield put({ type: RETWEET_FAILURE, error: err.response.data }); } }
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
[공유] input 속성에 hidden 이 적용 안될 때
<input type='file' multiple style={{ display: 'none' }} />display: 'none'으로 줘보세요!
-
해결됨손에 익는 Next.js - 공식 문서 훑어보기
Revalidate 부분 질문
질문 가이드 📖 안녕하세요.강의 중 날씨 데이터 재검증하기 부분에서 코드를 강사님 코드를 따라하다가시간 api fetch 부분에서 아래와 같은 에러가 발생이 되어서 질문 드립니다.강사님 코드를 깃에서 받아서 IDE (vscode, webstorm) 열어봐도 똑같은 현상이 보입니다.혹시 이런 부분에 대해서 알고 계신 내용이 있으시다면 답변주시면 감사드리겠습니다. 참고로 노드 버전은 20.9.0입니다!
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 레딧 사이트 만들기(NextJS)(Pages Router)
회원가입 누르면 404에러가 뜹니다 ;-;
안녕하세요 ;-;회원가입 누르니 404에러가 뜹니다..완성 코드랑 비교해서 봐도 똑같은데 어떤 문제인지 모르겠스빈다... next.js가 13이긴 합니다만 ;-; 그 이유 일까요?.. 어디를 살펴보면 될까요?;-;
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
faker 적용 후 이미지가 깨지는 오류, 게시글 이미지 클릭 시 이미지 확대 화면의 fill-rule(fillRule) 에러에 관한 질문
안녕하세요! React로 NodeBird SNS 만들기섹션3 Redux-saga 연동까지 모두 수강한 수강생입니다!사전에 제로초님 강의와 트위터 클론 깃허브를 확인하였고, 구글링 및 에러를 번역했습니다!항상 강의 잘 보고 있습니다! 제로초님 항상 감사합니다!(1) 아래 질문 글과 동일하게 faker 이미지가 깨지는 현상이 발생했습니다!https://www.inflearn.com/course/lecture?courseSlug=%EB%85%B8%EB%93%9C%EB%B2%84%EB%93%9C-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%A6%AC%EB%89%B4%EC%96%BC&unitId=48831&category=questionDetail&tab=community&q=451330lorempixel 사이트 고장이 원인이라 다른 대체 사이트(placeimg)를 찾아봤지만 해결이 되지 않아 질문 올립니다!옆의 에러를 번역해보니 사이트 자체에서 이미지 찾을 수 없다고 합니다!+++(2) Warning: Invalid DOM property fill-rule. Did you mean fillRule? 에러게시글 이미지 클릭 시 콘솔에 fill-rule 에러가 발생합니다!faker 적용 전, 게시글 더미이미지가 있었을 때도 똑같은 에러가 발생하였습니다!더미이미지 삭제 전에도 진행 자체에 문제가 없고, 콘솔에 오류만 출력 되었는데 그냥 넘어가도 되는 에러인지 궁금합니다!(svg 관련 이미지는 적용한 적이 없습니다!)에러를 번역해보니 다음과 같았습니다.
-
미해결[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
이벤트 위임 관련 질문드려요!
안녕하세요!이벤트 위임이란 이벤트 버블링을 이용하여 상위 태그에 이벤트 핸들러를 할당하여 하위 태그에서 중복되는 이벤트들을 없앨 수 있다. 이 과정에서 원치 않은 이벤트 버블링를 막기 위해서는 event.stopPropagation() 함수를 사용해야 한다. 라고 이해했습니다.이벤트 위임 관련해서 구글링 해보니, 구현 방식에 있어서 자바스크립트와 리액트에서 차이가 있다고 보았는데 자료들이 부정확하고 이해하기 어려워서 질문드립니다. 리액트와 자바스크립트에서 이벤트 버블링 구현시 어떤 차이가 있으며 그 이유와 원리에 대해 설명 부탁드립니다..!항상 좋은 강의 감사드립니다이벤트 위임 관련 아래 링크 첨부합니다.https://github.com/facebook/react/issues/13635https://github.com/facebook/react/issues/13625
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
이벤트 핸들러 관련 질문드려요!
안녕하세요! 이벤트처리 함수 관련해서 질문드립니다.현재는 event를 넘겨서 처리하고 있다보니 currentTaget이니 target이니 신경 쓸 것이 많은데, <div onClick(() => onClickAlert(el.writer)} > 이렇게 바로 id의 값을 바인딩시켜줘도 되지 않나요?혹시 수업에서와 같이 <div id={el.writer} onClick={onClickAlert}> id 속성을 부여하고 이를 onClickAlert에서 event를 받아서 처리해야만 하는 상황이나 위와 같이 했을 때의 이점이 있는지 궁금합니다!항상 좋은 강의 감사드려요!
-
해결됨손에 익는 Next.js - 공식 문서 훑어보기
서버 컴포넌트 관련 질문입니다!
SSR 방식에 서버 컴포넌트와 클라이언트 컴포넌트를 둘 다 적절히 사용하는 것인가요??서버 컴포넌트는 데이터 페칭, 보안, 캐싱, JS 번들크기 감소와 같은 장점이 있고 event와 hook을 사용하지 못한다는 특징도 이야기해주셨는데, 그렇다면 데이터를 받아서(페칭해서) 클라이언트 컴포넌트에 데이터를 뿌려주는 느낌으로 조합해서 사용하는 건가요??서버컴포넌트는 event를 사용하지 않으므로, TTI를 개선하기 위해 나온 개념은 아닌거죠???
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
이거 배우면은 카페24를 자유자제로 쇼핑몰을 꾸밀 수 있나요?
이거 배우면은 카페24를 자유자제로 쇼핑몰을 꾸밀 수 있나요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
모바일의 경우 리디렉션에 대해 궁금증이 있습니다.
포트원 개발자 센터를 보면, 모바일의 경우 리디렉션을 하면서 쿼리스트링으로 imp_uid 등등의 데이터를 붙여서 보내주는걸로 보입니다. 해당 경우 리코일데이터를 비롯한 모든 데이터가 초기화 되지 않나요? 그렇다면, 로그인 정보를 비롯한 이런저런 데이터들은 어떻게 유지하고 있나요?로컬스토리지나 세션스토리지에 있는 엑세스토큰등을 이용해 아예 새롭게 데이터를 불러와야 하는걸까요?
-
미해결따라하며 배우는 리액트 A-Z[19버전 반영]
create-react-app 관련
npx create-react-app 이렇게 만들면 src폴더 없이 만들어지더라구요 그래서 그냥 npx 없이 만드니까 정상적으로 잘 만들어지는데 npx가 있는거와 없는거의 차이점이 뭔지 궁금합니다
-
미해결따라하며 배우는 리액트 A-Z[19버전 반영]
css를 불러오지 않아도 클래스 이름을 부여하여 스타일이 가능한가요?
useParams를 이용한 영화 상세 페이지 구현 파트8분 45초에서 css 파일을 불러오지 않고도modal__poster-img 클래스 이름을 부여하자 스타일이 반영되는 것을 확인할 수 있었습니다왜 이렇게 되는 걸까요?
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
로그인 실패 에러 (500 Internal Server Error)
회원가입 시 MySQL 테이블에 이메일, 비밀번호 저장되는 것을 확인하고 로그인을 시도했는데 계속 실패해서 질문드립니다 MySQL 워크벤치로 확인한 user 테이블을 보면 회원가입은 잘 되었는데 id: 2 의 메일, 비밀번호로 로그인이 안 됩니다 console.log로 확인해보니까 패스포트 로그인 시도에서 에러가 나는 것 같기는 한데 정확한 원인을 못 찾겠습니다.. 터미널에 뜨는 메시지입니다개발자도구_네트워크 화면입니다개발자도구_콘솔 화면입니다 의심스러운 코드입니다!routes/user.js 코드const express = require('express'); const bcrypt = require('bcrypt'); const passport = require('passport'); const { User } = require('../models'); const router = express.Router(); router.post('/login', (req, res, next) => { passport.authenticate('local', (err, user, info) => { if (err) { //서버쪽 에러 console.error(err); console.log('routes/user_server err') return next(err); } if (info) { //클라이언트쪽 에러 return res.status(401).send(info.reason); } return req.login(user, async (loginErr) => { if (loginErr) { //패스포트 로그인 에러 console.error(loginErr); console.log('routes/user_loginErr') return next(loginErr); } // res.setHeader('Cookie', 'cxlhy..랜덤토큰') return res.status(200).json(user); }); })(req, res, next); }); router.post('/', async (req, res, next) => { // POST /user try { const exUser = await User.findOne({ where: { email: req.body.email, } }); if (exUser) { return res.status(403).send('이미 가입된 메일입니다.'); } const hashedPassword = await bcrypt.hash(req.body.password, 10); //10~13 await User.create({ email: req.body.email, nickname: req.body.nickname, password: hashedPassword, }); res.status(201).send('OK'); } catch (error) { console.error(error); next(error); //next로 에러 처리 (한방에), status 500 } }); module.exports = router; app.js 코드const express = require('express'); const cors = require('cors'); const session = require('express-session'); const cookieParser = require('cookie-parser'); const passport = require('passport'); const dotenv = require('dotenv'); const postRouter = require('./routes/post'); const userRouter = require('./routes/user'); const db = require('./models'); const passportConfig = require('./passport'); dotenv.config(); const app = express(); db.sequelize.sync() .then(() => { console.log('db 연결 성공'); }) .catch(console.error); passportConfig(); app.use(cors({ origin: 'http://localhost:3000', credentials: false, })); app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.use(cookieParser(process.env.COOKIE_SECRET)); app.use(session({ saveUninitialized: false, resave: false, secret: process.env.COOKIE_SECRET, })); app.use(passport.initialize()); app.use(passport.session()); ~이하생략~ passport/index.js 코드const passport = require('passport'); const local = require('./local'); const { User } = require('../models'); module.exports = () => { passport.serializeUser((user, done) => { done(null, user.id); }); passport.deserializeUser(async (id, done) => { try { const user = await User.findOne({ where: { id } }); done(null, user); //req.user } catch (error) { console.error(error); done(error); } }); local(); }; passport/local.js 코드const passport = require('passport'); const { Strategy: LocalStrategy } = require('passport-local'); const bcrypt = require('bcrypt'); const { User } = require('../models'); module.exports = () => { passport.use(new LocalStrategy({ usernameField: 'email', //id칸 passwordField: 'password', //비밀번호칸 }, async (email, password, done) => { //done으로 결과 판단 try { const user = await User.findOne({ //가입된 이메일이 있는지 검사 where: { email } }); if (!user) { return done(null, false, { reason: '존재하지 않는 이메일입니다.' }); } const result = await bcrypt.compare(password, user.password) if (result) { return done(null, user); } return done(null, false, { reason: '비밀번호가 일치하지 않습니다.' }); } catch (error) { console.error(error); return done(error); } })); };
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
newaccessToken 질문드립니다
만약에 지금 발급된 accessToken 이 만료되지 않은 상황이라면 해당 강의에서의 aaa.toPromise().then((newAccessToekn) =>{}) 함수 실행시에 newAccessToken 이 발급되지 않는 걸까요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
수업 정답코드좀 알려주세요
이부분 이거 말고도 소과제 있는 부분 전부 다 정답코드 어디에 있나요? 아무리 찾아도 안나와요 자세한 경로좀 알려주세요
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
서버사이드 렌더링 적용 후, css가 풀렸다가 다시 적용되는것 같아요.
안녕하세요!서버사이드 렌더링 적용후에 css가 풀렸다가 다시적용되는 것 같은데, 해결 방법이 있을까요?로그인 후 새로고침을 하면 잠깐 첫번째 화면이 보였다가 두번째 화면을 보여줍니다. 세번째 화면은 리덕스 상태입니다.서버사이드 렌더링을 해서 user와 post의 데이터는 잘 받아오고 있는것 같습니다.
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
섹션 13 대댓글 과제 관련 질문
안녕하세요 과제로 받은 자유게시판 대댓글 기능 구현과 관련한 질문이 있어 글 남깁니다 우선 포트폴리오 과제를 진행할 때 사용하는 플레이그라운드 주소는https://backend-practice.codebootcamp.co.kr/graphql다음과 같습니다 플레이그라운드를 확인해보니 대댓글과 관련된 쿼리와 뮤테이션은UseditemQuestions, UseditemQuestionAnswers 인 것 같은데요대댓글과 관련된 다른 질문들을 통해 댓글=질문, 대댓글=질문에 대한 답변으로 생각하면 된다는 답변을 보았습니다 현재 자유게시판 댓글과 관련된 과제를 진행할 때 사용한 쿼리와 뮤테이션은BoardComments 인데요그러면 BoardComment 쿼리와 뮤테이션을 사용해 구현한 댓글 기능을 UseditemQuestion으로 변경해야 대댓글 기능을 구현할 수 있는 건가요?
-
미해결[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
댓글 삭제 시 애니메이션 추가하고싶습니다.
안녕하세요. 현재 댓글 수정, 삭제 구현중에 있습니다.강의 과정에는 없지만 추가적으로 궁금한 부분이 있어 질문 드립니다. 댓글을 삭제하는 경우, 바로 반영되어 댓글이 삭제되기는 하나애니메이션을 적용시켜 천천히 사라지며 삭제되는 코드를 짜고싶습니다.현재 TransitionGroup, CSSTransition, keyframes 컴포넌트를 사용해애니메이션은 적용이 되고 있으나, 삭제시 삭제되는 해상 댓글에만 적용하기는 너무 어렵네요생각하기로는, 해당 댓글의 id 값을 스타일시트로 받아와서 스타일시트에서 해당 _id의 댓글만 애니메이션을 적용하면 될 것 같은데 생각대로 되지 않는 것 같습니다.어떻게 하면 좋을지 힌트라도 얻을 수 있을까요? import { getDateTime } from '../../../../commons/libraries/utils'; import * as S from './BoardCommentDetail.styles'; import { TransitionGroup, CSSTransition } from 'react-transition-group'; import { useEffect } from 'react'; export default function BoardCommentDetailUI(props) { useEffect(() => { // 댓글이 변경될 때 추가적인 정리 또는 부작용을 수행할 수 있습니다. }, [props.data?.fetchBoardComments]); return ( <div> <TransitionGroup> {props.data?.fetchBoardComments.map((el) => ( <CSSTransition> <S.CommentWrapper> <S.Comment> <S.ProfileImg> <img src={`/img/profileIcon.svg`} width={48} height={48} /> </S.ProfileImg> <S.CommentContentsArea> <S.CommentContentsWriter> <S.ContentsWriter>{el.writer}</S.ContentsWriter> <S.ContentsRate value={el.rating} disabled /> </S.CommentContentsWriter> <S.CommentContents>{el.contents}</S.CommentContents> <S.CommentDate>{getDateTime(el.createdAt)}</S.CommentDate> </S.CommentContentsArea> <S.WriterIconWrapper> <img src={`/img/mode-24px.svg`} /> </S.WriterIconWrapper> <S.WriterIconWrapper id={el._id} onClick={() => props.onClickDeleteComment(el._id)} > <img src={`/img/clear-24px.svg`} /> </S.WriterIconWrapper> </S.Comment> </S.CommentWrapper> </CSSTransition> ))} </TransitionGroup> </div> ); }import { useMutation, useQuery } from '@apollo/client'; import { FETCH_BOARD_COMMENTS, DELETE_BOARD_COMMENT, } from './BoardCommentDetail.queries'; import { useRouter } from 'next/router'; import BoardCommentDetailUI from './BoardCommentDetail.presenter'; import { useState } from 'react'; export default function BoardCommentDetail() { const router = useRouter(); const [commentIdToDelete, setCommentIdToDelete] = useState(null); const { data, refetch } = useQuery(FETCH_BOARD_COMMENTS, { variables: { boardId: router.query.boardId }, }); const [deleteBoardComment] = useMutation(DELETE_BOARD_COMMENT); const onClickDeleteComment = async (commentId) => { setCommentIdToDelete(commentId); const isConfirmed = window.confirm('댓글을 삭제하시겠습니까?'); if (isConfirmed) { try { const passwordConfirmation = prompt('비밀번호를 입력하세요'); await deleteBoardComment({ variables: { boardCommentId: commentId, password: passwordConfirmation, }, }); alert('댓글이 삭제되었습니다.'); refetch(); } catch (error) { console.error('댓글 삭제 중 오류 발생', error); } } }; return ( <BoardCommentDetailUI data={data} onClickDeleteComment={onClickDeleteComment} /> ); }
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
15:24 초에 createBoard 값으로 받은 result 값
15:24 초에 createBoard 값으로 받은 result 값을콘솔에 찍어보면data.createBoard 값에 저장된 값이_typename , _id 값 두개만 보이는데백엔드 API 설계 당시에 뮤테이션의 리턴값으로 저 2개의 ㄱ값만 리턴하도록 설정되어 있는 건가요? 아님 요약 정보만 추려서 보여주는 건가요?