inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

묻고 답해요

172만명의 커뮤니티!! 함께 토론해봐요.

section8 포폴 리뷰 에러가 납니다.

해결됨

[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스

boards/new/index.js 에서 항목 기입 후 등록하기 버튼을 누를 시 등록된 상세페이지로 넘어가지 않고 alert 알림창으로 "Response not successful: Received status code 400" 이렇게 뜹니다. 오타는 혹시 있나 해서 올려주신 깃허브랑 하나하나 꼼꼼히 비교 했는데 없었어요.. 오류코드를 개발자도구로 뜯어보니 그래서 해당 부분 확인해봐도 모두 강사님과 동일하게 작성되있는데 뭐가 문제일까요

  • react
  • node.js
  • seo
  • graphql
  • next.js
초록 댓글 1 좋아요 0 조회수 316

특정 페이지의 비로그인 차단

해결됨

[리뉴얼] React로 NodeBird SNS 만들기

강좌에서처럼 me(내 정보 불러오는 상태변수) 변수를 통해 로그인 유지를 하고 특정 페이지에서 비로그인 사용자를 차단할경우 useEffect(() => { if(!me){ redirects(); } },[]) 이런식으로 로직을 짤수가 있는데 문제가 브라우저 url로 접속할 경우 초기 me 의 상태가 null 이기 때문에 로그인을 한 상태더라도 리다이렉트가 되는 문제가 있었습니다. 물론 ssr을 이용하면 이 문제가 해결은 되지만 csr만 이용하는 선에서 리다이렉트가 정상적으로 작동하도록 하고 싶은데 어떻게 하면 좋을까요?

  • react
  • redux
  • node.js
  • express
  • next.js
kenny 댓글 1 좋아요 0 조회수 369

Querydsl SQLExpressions에 listagg 관련 질문

미해결

안녕하세요, 김영한 님. Querydsl SQLExpressions에 listagg 관련하여 질문이 있습니다. 현재 Projections.constructoer 방식으로 조회한 결과를 Dto로 받고있는데요, SQLExpressions.listagg(컬럼, ",").withinGroup().orderBy(컬럼).getValue().as("listaggs") 로 select후 Dto에서 String으로 못받는데 String으로 받으려면 어떻게 해야 될까요? 방법이 없는걸까요? 이미 같은 질문을 남긴 글이 있는데 미해결 상태라 다시 한번 글 올려 봅니다. 이방법을 사용하는 이유는 A 테이블, B 테이블이 있는데 1:N의 관계 입니다) A테이블 조회시 Response에는 B테이블의 컬럼 하나도 추가로 목록에 보여줘야 하는데 그럴때 B테이블의 해당 컬럼의 값이 다른 데이터가 2개 이상일시 A정보가 2건이 나오게 되서 (페이징 처리시에도 총 카운트와 페이징 처리가 제대로 되지 않습니다.) 한 row로 보여지게 하기 위해 사용하려 Querydsl SQLExpressions에 listagg 사용하려는데, String으로 받을수가 없더군요... 혹 Querydsl SQLExpressions에 listagg 아니더라도 다른 방법이 있을까요?

  • jpa
  • querydsl
  • java
skyghy3342 댓글 1 좋아요 0 조회수 1028

블로그 학습일지 저작권 관련 문의

해결됨

[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스

안녕하세요 저작권 관련 질문드립니다! 본 학습 자료의 저작권은 코드캠프에 있어 무단 도용, 배포, 복제를 금지한다고 적혀있는데 그럼 혹시 개인 블로그에 내용을 공부한 내용을 정리한 것을 공개 처리해두어도 문제가 되지 않을지 문의드립니다.

  • react
  • node.js
  • seo
  • graphql
  • next.js
lumpyspaceyz 댓글 1 좋아요 0 조회수 368

포트폴리오 깃허브

해결됨

[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스

포트폴리오를 깃허브에 올리려고 하는데 git허브강좌 보면서 따라하고 있었는데 git add . 후 git status 하면은 해당 오류가 떠요 .. admin@DESKTOP-8KF9PK5 MINGW64 ~/Desktop/portfolio (master) $ git add . admin@DESKTOP-8KF9PK5 MINGW64 ~/Desktop/portfolio (master) $ git status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: freeboard_frontend Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) (commit or discard the untracked or modified content in submodules) modified: freeboard_frontend (modified content, untracked content) 해당 폴더 구조는 이렇습니다 보니까 .git이 이중으로 설치되어 있는데 어디 부분을 어떤 명령어로 삭제해야하는지 알려주시면 감사하겠습니다..!

  • react
  • node.js
  • seo
  • graphql
  • next.js
윰이 댓글 1 좋아요 0 조회수 460

콘솔로그가 2번 찍히는데 이유를 잘 모르겠습니다.

해결됨

[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스

05-05-dynamic-routing-board-mutation 강의에 있는 내용을 구현했습니다 이상은 없게 정상 작동하는데 콘솔로그가 2번 찍히는데 이해가 가지 않습니다 =========================================== 폴더구조 ================================================ 05-05-dynamic-routing-board-mutation/index.js import {gql, useMutation} from "@apollo/client"; import {useRouter} from "next/router"; const 나의그래프큐엘세팅 = gql` mutation createBoard($writer: String, $title: String, $contents: String){ createBoard(writer: $writer, title: $title, contents: $contents){ _id number message } } ` export default function GraphqlMutationPage() { const router = useRouter() const [나의함수] = useMutation(나의그래프큐엘세팅) const onClickSubmit = async () => { try{ // try에 있는 내용을 시도하다가 실패하면, 다음에 있는 모든 줄들을 모두 무시하고, catch에 있는 내용이 실행됨. const result = await 나의함수({ variables: { writer: "호날두", title: "모두다 외쳐", contents: "Siuuuu~~~~~~" } }) //console.log("result 값은 다음과 같습니다", result) //console.log("동적라우팅 주소는 number라고 지칭했고 다음과 같아요", result.data.createBoard.number) // router.push('/section05/05-05-dynamic-routing-board-mutation-moved' + result.data.createBoard.number) router.push(`/section05/05-05-dynamic-routing-board-mutation-moved/${result.data.createBoard.number}`) }catch (error){ alert(error.message) } } return <button onClick={onClickSubmit}>GRAPHQL-API 요청하기</button> // 한줄일 때는 괄호 ( ) 가 필요없다. } =========================================================== 05-05-dynamic-routing-board-mutation-moved/[number]/index.js import {gql, useQuery} from "@apollo/client"; import {useRouter} from 'next/router' const FETCH_BOARD = gql` query fetchBoard($number: Int){ fetchBoard(number:$number){ # 1번 게시글 내용에 생략된 내용이 많아서 19047을 1번 게시글로 가정 number writer title contents } } ` export default function StaticRoutingMovedPage(){ const router = useRouter() console.log("라우터에 뭐가 들어있는지 알아보기",router) const { data } = useQuery(FETCH_BOARD, { variables: { number: Number(router.query.number) } }) console.log("데이터에 뭐가 들어있는지 알아보기",data) return( <> <div>{router.query.number}번 게시글 이동이 완료됐어요!!😀😀</div> <div>작성자: {data && data.fetchBoard?.writer}</div> <div>제목: {data?.fetchBoard?.title}</div> <div>내용: {data? data.fetchBoard?.contents : "로딩중입니다."}</div> </> ) } ================================================================== 브라우저 콘솔창 -> 여기서 GraphQL요청 후 콘솔 찍어놓은게 2번 반복됩니다. 위의 내용 확대 ================================================================== 네트워크 탭 여기에 GraphQl 요청이 두번 나간 것 같은데 그것 때문에 그런 건가요? 아니면 data 내용을 콘솔 찍었을때 한번 undefined 처리가 되어서 데이터를 받아오는 과정에서 한번 더 콘솔이 찍힌건가요?

  • react
  • node.js
  • seo
  • graphql
  • next.js
Jun 댓글 1 좋아요 0 조회수 332

useRouter 를 import 할때 next/router만 뜨는 경우

해결됨

손에 익는 Next.js - 공식 문서 훑어보기

챕터3-2 useRouter 를 import하는데 navigation router 는 import 가 되지 않네요.. 혹시 따로 설치를 해야하는 부분인가요?

  • react
  • typescript
  • next.js
  • next.js13
가스라이팅의정석 댓글 2 좋아요 0 조회수 652

deleteUser 관련 질문

미해결

자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]

현재 코드에서는 name을 기준으로 delete를 하는데요, findByName(name)을 이용한 코드에서 DB 안에 같은 이름의 회원이 2명 이상인 경우엔 오류가 생깁니다. 그 이유가 find는 return 개수가 1건이기 때문에 rollback 된다고 생각했습니다. 이 버그를 수정하기 위해서 deleteUser의 파라미터는 Long id 로 수정했는데, 또 안 되더라고요...? findAll을 쓰면 같은 이름을 가진 모든 회원이 삭제될 것 같고... 어떻게 하면 동명이인의 회원 중에서 내가 원하는 한 회원만 삭제할 수 있나요? + 추가 방금 다른 학생분의 질문과 답변을 읽었습니다. 같은 내용의 질문인 것 같네요! 그러면 파라미터를 Long id 로 변경하되, 현재 실습 중인 UI에서도 코드를 수정해야하는 부분이 있기에 삭제가 안 되는 게 맞다고 이해하면 될까요?

  • java
  • spring
  • aws
  • mysql
  • spring-boot
  • jpa
alstjs 댓글 1 좋아요 1 조회수 228

안녕하세요 제로초님 로그인 관련 redux 질문있습니다.

미해결

[리뉴얼] React로 NodeBird SNS 만들기

다름이 아니라 제로초님의 로그인 문제 해결하기 챕터를 보다가 Posts.length관련 오류 해결하는 강의를 보는데 제로초님의 redux화면이랑 저의 화면이랑 구성이 좀 다른 것 같아서 문의드립니다. 제로초님의 화면은 위 사진처럼 me라는 객체로 나와서 확인하기 쉬운데 제 화면은 아래처럼 그냥 데이터 라고 나오고 있습니다.. 어느 부분을 수정해야하는지 잘 모르겠어서 질문드립니다.

  • react
  • redux
  • node.js
  • express
  • next.js
윤채현 댓글 1 좋아요 0 조회수 302

글 작성이 안 되는 오류

해결됨

[리뉴얼] React로 NodeBird SNS 만들기

컴파일은 오류 없이 잘 되는데, 폼에서 짹짹(게시)버튼을 눌러도 글 작성이 되지 않습니다 개발자도구에서 나타나는 오류입니 Incorrect use of <label for=FORM_ELEMENT> The label's for attribute doesn't match any element id . This might prevent the browser from correctly autofilling the form and accessibility tools from wo rking correc tly. To fix this issue, make sure the label's for attribute references the correct id of a form field. PostCard가 작성되지 않는데 코드에서 오류를 못 찾겠어서 질문합니다! 의심스러운 부분들만 올려봅니다.. post.js 코드입니다 const ADD_POST = 'ADD_POST'; export const addPost = { type: ADD_POST } const reducer = (state = initialState, action) => { switch (action.type) { case ADD_POST: { return { ...state, mainPosts: [dummyPost, ...state.mainPosts], postAdded: true, }; }; default: { return { ...state, }; }; } }; PostForm.js 코드입니다 const PostForm = () => { const { imagePaths } = useSelector((state) => state.post); const dispatch = useDispatch(); const imageInput = useRef(); const [text, setText] = useState(''); const onChangeText = useCallback((e) => { setText(e.target.value); }, []); const onSubmit = useCallback(() => { dispatch(addPost); setText('') }, []); return ( <Form style={{ margin: '10px 0 20px' }} encType="multipart/form-data" onFinish={onSubmit}> <Input.TextArea value={text} onChange={onChangeText} maxLength={140} placeholder='새로운 글 작성' /> <div> <input type="file" multiple hidden ref={imageInput} /> <Button onClick={onClickImageUpload}>이미지 업로드</Button> <Button type="primary" style={{ float: 'right' }} htmlType="submit">게시</Button> </div> <div> {imagePaths?.map((v) => ( <div key={v} style={{ display: 'inline-block' }}> <img scr={v} style={{ width: '200px' }} alt={v} /> <div> <Button>제거</Button> </div> </div> ))} </div> </Form> ) }; pages/index.js 코드입니다 const Home = () => { const { isLoggedIn } = useSelector((state) => state.user); const { mainPosts } = useSelector((state) => state.post); return ( <AppLayout> {isLoggedIn && <PostForm />} {mainPosts.map((post) => <PostCard key={post.id} post={post} />)} </AppLayout> );

  • react
  • redux
  • node.js
  • express
  • next.js
sscapstondesign3 댓글 1 좋아요 0 조회수 670

로그 결과값 표기 이상

해결됨

[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스

안녕하세요, 수업 도중에 콘솔에 찍힌 결과가 이해가 되지 않아 문의 남깁니다.persons에 "철수"부터 "영수"까지 for문에 결과가 총 6번 나와야 하는데 4개 값 밖에 안나와 해당 이유. 궁금합니다,

  • react
  • node.js
  • seo
  • graphql
  • next.js
유클리드소프트 댓글 1 좋아요 0 조회수 215

docker-compose.yml 은 왜 루트에 하나염

미해결

따라하며 배우는 노드, 리액트 시리즈 - 레딧 사이트 만들기(NextJS)(Pages Router)

docker-compose.yml 은 왜 루트에 두나요?.?~

  • react
  • node.js
  • postgresql
  • docker
  • typescript
  • 클론코딩
  • next.js
장진 댓글 1 좋아요 0 조회수 339

04-05-graphql-mutation-product

해결됨

[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스

마지막 createProduct 불러오는 부분에서 createProductInput 부분에 제공되는 값이 없다고 뜨는 것 같습니다. 오타나 변수를 확인해봐도 제 눈에는 안보여서.. 이 부분에서 오류가 나는건 맞는 것 같은데 서버에서 못받아오는걸까요? 어떤게 문제일까요?ㅠㅠ 작성코드도 같이 첨부합니다..!

  • react
  • node.js
  • seo
  • graphql
  • next.js
댓글 1 좋아요 0 조회수 368

새로고침시 캐싱 안되는 현상

해결됨

손에 익는 Next.js - 공식 문서 훑어보기

안녕하세요! 캐싱 관련하여 질문드립니다. 날씨 데이터 재검증하기 챕터에서 강의를 봤을 때는 새로고침을 해도 기존 응답값을 캐싱해서 보여주는 것 같은데 제가 따라해봤을 떄는 새로 고침시에는 apI를 새로 불러와서 보여주고 라우팅 이동 중에는 캐싱된 값을 보여주고 있습니다. 그래서 깃헙에 있는 코드를 클론 받아서 실행을 해봤는데 마찬가지로 새로고침시 시간이 유지되지 않고 변경이 됩니다. 현재 상황은 이런데 어떤 부분을 확인하면 좋을까요? 영상 첨부합니다.

  • react
  • typescript
  • next.js
  • next.js13
Hoseok Na 댓글 1 좋아요 0 조회수 517

로그아웃시 req logout의 콜백함수 에러가 납니다...

해결됨

[리뉴얼] React로 NodeBird SNS 만들기

req.logout을 호출할때 콜백함수가 필요하다 라고 나옵니다. req#logout requires a callback function 이런식으로요 제 코드는 제로초님 코드처럼 적어놨는데 제가 이해하는 콜백함수라는게 라우터 부분이라고 생각이 드는데 어떻게 수정을 해야할지 감이 안잡힙니다 ㅜㅜ const express = require('express'); const bcrypt = require('bcrypt'); const passport = require('passport'); const { isLoggedIn, isNotLoggedIn } = require('./middlwares') const { User, Post } = require('../models'); const router = express.Router(); router.post("/login", isNotLoggedIn, (req, res, next) => { passport.authenticate("local", (err, user, info) => { if (err) { // 서버에러 부분 console.error(err) return next(err) } if(info){// 클라이언트 에러 부분 return res.status(401).send(info.reason) } // 성공시 return req.login(user,async(loginErr)=>{ // 패스포트 에러날시 if(loginErr){ console.error(loginErr) return next(loginErr) } // 유저의 모든 정보 const fullUserWithoutPassword = await User.findOne({ where:{id:user.id}, // 비밀번호 제외 // 받고 싶은 정보만 적을경우 // attributes:["id","nickname","email"], attributes: { exclude:["password"] }, // 나머지 정보 include:[{ model:Post }, { model: User, as: "Followings", }, { model: User, as: "Followers", }] }) // post 팔로워 팔로잉 정보 비밀번호 제거 return res.status(200).json(fullUserWithoutPassword) }) })(req,res,next) }) router.post("/", isNotLoggedIn, async (req, res, next) => { 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, 12) await User.create({ email:req.body.email, nickname: req.body.nickname, password: hashedPassword, }) // res.setHeader("Access-Control-Allow-Origin","http://localhost:3000") res.status(201).send("회원가입이 완료되셨습니다.") // 201은 생성이 잘됫다. } catch (error) { console.error(error) next(error)// 에러가 난거를 브라우저에 알려준다. statsus:500 } }) router.post('/logout', (req, res) => { req.logout(); req.session.destroy(); res.send('ok'); }); module.exports = router

  • react
  • redux
  • node.js
  • express
  • next.js
GI P 댓글 1 좋아요 1 조회수 361

post 추가 시 오류

미해결

[리뉴얼] React로 NodeBird SNS 만들기

안녕하세요 제로초님 다름이 아니라 로그인 후 포스트를 추가할 때 에러가 발생하는데 혼자 해결하려고 노력해봤지만 해결을 아직 하지 못하여 질문드립니다. reducers/post.js import shortId from "shortid"; import { produce } from "immer"; import faker from "faker"; export const initialValue = { mainPosts: [], //이미지업로드 할떄 이미지경로들이 여기 들어간다. imagePaths: [], hasMorePost: true, //true면 가져올 시도를 해라. (스크롤 했을 때) loadPostsLoading: false, loadPostsDone: false, loadPostsError: null, //게시글 추가가 완료되었을때 TRue addPostLoading: false, addPostDone: false, addPostError: null, removePostLoading: false, removePostDone: false, removePostError: null, addCommentLoading: false, addCommentDone: false, addCommentError: null, }; //가짜 데이터 export const generateDummyPost = (number) => Array(number) .fill() .map(() => ({ id: shortId.generate(), User: { id: shortId.generate(), nickname: faker.name.findName(), }, content: faker.lorem.paragraph(), //아무 문장, Images: [ { src: "https://image.utoimage.com/preview/cp872722/2022/12/202212008462_500.jpg", }, ], Comments: [ { User: { id: shortId.generate(), nickname: faker.name.findName(), }, content: faker.lorem.sentence(), }, ], })); export const LOAD_POSTS_REQUEST = "LOAD_POSTS_REQUEST"; export const LOAD_POSTS_SUCCESS = "LOAD_POSTS_SUCCESS"; export const LOAD_POSTS_FAILURE = "LOAD_POSTS_FAILURE"; export const ADD_POST_REQUEST = "ADD_POST_REQUEST"; export const ADD_POST_SUCCESS = "ADD_POST_SUCCESS"; export const ADD_POST_FAILURE = "ADD_POST_FAILURE"; export const REMOVE_POST_REQUEST = "REMOVE_POST_REQUEST"; export const REMOVE_POST_SUCCESS = "REMOVE_POST_SUCCESS"; export const REMOVE_POST_FAILURE = "REMOVE_POST_FAILURE"; export const ADD_COMMENT_REQUEST = "ADD_COMMENT_REQUEST"; export const ADD_COMMENT_SUCCESS = "ADD_COMMENT_SUCCESS"; export const ADD_COMMENT_FAILURE = "ADD_COMMENT_FAILURE"; export const addPost = (data) => ({ type: ADD_POST_REQUEST, data, }); export const addComment = (data) => ({ type: ADD_COMMENT_REQUEST, data, }); //리듀서란 이전 상태를 액션을 통해 다음 상태로 만들어내는 함수(단, 불변성은 지키면서) //draft는 불변성 상관없이 바꾸면 immer가 알아서 불변성있게 만들어준다. const reducer = (state = initialValue, action) => produce(state, (draft) => { switch (action.type) { //게시글 추가 case ADD_POST_REQUEST: draft.addPostLoading = true; draft.addPostDone = false; draft.addPostError = null; break; case ADD_POST_SUCCESS: draft.addPostLoading = false; draft.addPostDone = true; draft.mainPosts.unshift(action.data); draft.imagePaths = []; //unshift란 배열의 맨 앞에다가 추가하는 함수 break; case ADD_POST_FAILURE: draft.addPostLoading = false; draft.addPostError = action.error; break; //게시글 불러오기 case LOAD_POSTS_REQUEST: draft.loadPostsLoading = true; draft.loadPostsDone = false; draft.loadPostsError = null; break; case LOAD_POSTS_SUCCESS: draft.loadPostsLoading = false; draft.loadPostsDone = true; draft.mainPosts = action.data.concat(draft.mainPosts); //concat은 두개 이상의 배열을 합칠 때 사용 //action.data에는 더미데이터들이 들어있고 draft.mainPosts는 원래 데이터 draft.hasMorePost = draft.mainPosts.length < 50; //50개보다 적으면 불러와야함 break; case LOAD_POSTS_FAILURE: draft.loadPostsLoading = false; draft.loadPostsError = action.error; break; //댓글 추가 case ADD_COMMENT_REQUEST: draft.addCommentLoading = true; draft.addCommentDone = false; draft.addCommentError = null; break; case ADD_COMMENT_SUCCESS: //immer버전 (너무 간단함) const post = draft.mainPosts.find( (v) => v.id === action.data.postId ); //해당 게시글 찾기 post.Comments.unshift(dummyComment(action.data.content)); draft.addCommentLoading = false; draft.addCommentDone = true; //댓글 넣어주기 break; //immer를 안 쓴 부분 // const postIndex = state.mainPosts.findIndex( // (v) => v.id === action.data.postId // ); // const post = { ...state.mainPosts[postIndex] }; // post.Comments = [ // dummyComment(action.data.content), // ...post.Comments, // ]; //얕은 복사 // const mainPosts = [...state.mainPosts]; // mainPosts[postIndex] = post; //댓글 추가하는 부분 너무어려움.. // //불변성을 지키다 보니 가독성이 너무 안좋음 // return { // ...state, // mainPosts, // addCommentLoading: false, // addCommentDone: true, // }; case ADD_COMMENT_FAILURE: draft.addCommentLoading = false; draft.addCommentError = action.error; break; //게시글 삭제 case REMOVE_POST_REQUEST: draft.removePostDone = false; draft.removePostLoading = true; draft.removePostError = null; break; case REMOVE_POST_SUCCESS: draft.removePostLoading = false; draft.removePostDone = true; draft.mainPosts = draft.mainPosts.filter( (v) => v.id !== action.data ); break; case REMOVE_POST_FAILURE: draft.removePostLoading = false; draft.removePostError = action.error; break; default: break; } }); export default reducer; 여기서 Images안에 아무것도 들어있지 않아서 나타나는 오류같은데 잘 모르겠습니다.

  • react
  • redux
  • node.js
  • express
  • next.js
윤채현 댓글 1 좋아요 0 조회수 277

&lt;StopOutLined&gt; 이 exported 되지 않는 오류

해결됨

[리뉴얼] React로 NodeBird SNS 만들기

import { List, Button, Card } from 'antd'; import { StopOutLined } from '@ant-design/icons'; 로 임포트를 했는데도 불구하고 프로필창을 열면 다음과 같은 에러가 납니다 터미널에는 에러메시지도 뜨고요 error - ./components/FollowList.js Attempted import error: 'StopOutLined' is not exported from '@ant-design/icons'. npm i antd antd 와 npm install @ant-design/icons --save-dev로 다시 설치해봤는데 해결되지 않았습니다 package.json 에서 확인한 버전입니다 "antd": "^5.10.2", "@ant-design/icons": "^5.2.6", FollowList.js 에서 의심스러운 부분입니다 import { List, Button, Card } from 'antd'; import { StopOutLined } from '@ant-design/icons'; const FollowList = ({header, data}) => { return ( <List renderItem={(item) => ( <List.Item style={{ marginTop: 20 }}> <Card actions={[<StopOutLined key="stop" />]}> <Card.Meta description={item.nickname} /> </Card> </List.Item> )} /> ) };

  • react
  • redux
  • node.js
  • express
  • next.js
sscapstondesign3 댓글 1 좋아요 0 조회수 382

섹션 31 댓글 기능 구현 과제 관련 질문

미해결

[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스

안녕하세요 섹션 31 댓글 기능 구현 과제 중 궁금한 점이 있어 질문 남깁니다 댓글 리스트의 수정 아이콘 클릭 시 사진과 같은 화면이 나오도록 했고, 댓글 등록하기 presenter component를 재사용 했습니다 댓글 리스트 presenter 파일입니다 export default function CommentListUI(props) { return ( <S.Wrapper> {props.data?.fetchBoardComments.map((item) => ( <S.CommentListWrapper key={item._id}> {props.isEdit && props.commentId === item._id ? ( <CommentWriteUI></CommentWriteUI> ) : ( <S.Comment_Container> <S.profile_icon src="/02/profile_icon.png"></S.profile_icon> <S.Content_container> <S.Name_Star_container> <S.Text style={{ fontWeight: "600" }}>{item.writer}</S.Text> <S.ReviewStar_container style={{ marginLeft: "16px" }}> <S.StarDiv></S.StarDiv> <S.StarDiv></S.StarDiv> <S.StarDiv></S.StarDiv> <S.StarDiv></S.StarDiv> <S.StarDiv></S.StarDiv> </S.ReviewStar_container> </S.Name_Star_container> <S.Text style={{ marginTop: "-15px", fontWeight: "500" }}> {item.contents} </S.Text> <S.Text style={{ fontSize: "12px", fontWeight: "400", color: "#BDBDBD", }} > {getDate(item.createdAt)} </S.Text> </S.Content_container> <S.Icon_container> <S.Icon style={{ backgroundImage: `url("/createComment.png")` }} onClick={() => props.onClickTEST(item._id)} ></S.Icon> <S.Icon style={{ backgroundImage: `url("/clear.png")` }} onClick={() => props.onClickDelete(item._id)} ></S.Icon> </S.Icon_container> </S.Comment_Container> )} </S.CommentListWrapper> ))} </S.Wrapper> ); } 삼항연산자를 사용해 나오는 화면을 다르게 했습니다 isEdit 변수는 수정하기 아이콘 클릭 시 true로 바뀌고, 삼항연산자 조건에 isEdit 변수만 사용하니 수정 아이콘을 클릭하지 않은 다른 댓글 리스트가 사라지면서 재사용한 댓글 등록 presenter 파일만 화면에 나와서 조건은 위와 같이 작성했습니다 여기서 문제는 수정 아이콘을 클릭해 나오는 댓글 등록 창은 container 파일에 작성한 함수가 작동하지 않는 것입니다 댓글 리스트 container 파일입니다 export default function CommentList() { const { data } = useQuery(FETCH_COMMENTS); const [deleteBoardComment] = useMutation(DELETE_COMMENTS); const onClickDelete = async (item) => { const pw = prompt("비밀번호를 입력해주세요."); try { await deleteBoardComment({ variables: { pw: pw, boardCommentId: item, }, refetchQueries: [{ query: FETCH_COMMENTS }], }); alert("삭제되었습니다."); } catch (error) { alert(error.message); } }; // 수정하기 아이콘 클릭 시 화면 변화 const [isEdit, setIsEdit] = useState(false); const [commentId, setCommentId] = useState(); const onClickTEST = (item) => { setIsEdit(true); setCommentId(item); }; // console.log(commentId); return ( <CommentListUI data={data} onClickDelete={onClickDelete} onClickTEST={onClickTEST} isEdit={isEdit} commentId={commentId} ></CommentListUI> ); } 댓글 등록 container 파일입니다 const [updateBoardComment] = useMutation(UPDATE_BOARD_COMMENT); const onClickUpdate = () => { // updateBoardComment({ // variables: { // updateBoardCommentInput: { // contents: contents, // rating: 0 // }, // password: pw, // boardCommentId: // } // }) console.log("Test"); }; return ( <> <CommentWriteUI onChangeWriter={onChangeWriter} onChangePw={onChangePw} onChangeContents={onChangeContents} onClickUpdate={onClickUpdate} ></CommentWriteUI> </> ); } onClickUpdate 함수는 댓글 작성 presenter 파일의 등록하기 버튼에 연결되어 있습니다 상세 페이지 로딩 시 나오는 댓글 등록창은 버튼 클릭 시 콘솔이 제대로 나오는데 댓글 리스트 수정 아이콘을 눌러 나오는 댓글 등록창에서는 버튼을 눌러도 콘솔 자체가 나오지 않습니다 댓글 과제 가이드를 확인해서 어떻게 수정하면 좋을지는 알았지만, 궁금한 점이 해소되지 않네요 궁금한 점은 삼항연산자, map 등 기능의 속성을 제대로 알지 못한 채 사용한 문제인지 코드 자체를 잘못 작성한 것인지 추가로 rating(별점) 데이터 활용법에 대한 힌트를 얻고 싶습니다 rating 값 1 = 별 1개 인가요? rating 숫자 데이터가 별과 어떻게 연결되는지 잘 모르겠습니다 부족한 점이 많아 질문이 너무 길어졌네요 항상 감사합니다

  • react
  • node.js
  • seo
  • graphql
  • next.js
zero.1.0.one.xx 댓글 2 좋아요 0 조회수 613

todoData.map 화살표 함수 질문

미해결

따라하며 배우는 리액트 A-Z[19버전 반영]

[JSX Key 속성 이해하기] 파트에서는 todoData에 map 메서드를 사용할 때 this.todoData.map((value) => ( <div style={this.getStsyle()} key={value.id}> <input type="checkbox" defaultChecked={false} /> {value.title} <button style={this.btnStyle}>X</button> </div> )) 로 return 없이 사용하셨는데 전 기존에는 this.todoData.map((value) => { return ( <div style={this.getStsyle()} key={value.id}> <input type="checkbox" defaultChecked={false} /> {value.title} <button style={this.btnStyle}>X</button> </div> ) }) 이렇게 사용했습니다 둘다 정상 동작하는데 차이점이 뭔지 궁금합니다

  • react
  • redux
  • tdd
  • typescript
  • next.js
  • 소프트웨어-테스트
wkdejrtlr 댓글 1 좋아요 0 조회수 336

인기 태그

인프런 TOP Writers

주간 인기글