inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

묻고 답해요

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

getServerSideProps

해결됨

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

안녕하세요 선생님, 알려주신 것처럼, getServerSideProps 를이용해서 쿠키가 있을때만 페이지를 접근 가능하게 했습니다. 근데 sub를 생성할 수 있는 버튼을 클릭하면 아래 주소로 이동 가능하게( router.push('/sub/create') ) 했는데 접근이 가능하네요? 이럴땐, 해당 버튼을 클릭하면 다시 login 페이지로 가도록 라우팅 처리를 또 해줘야 하는건가요?

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

스크롤링 success 문제

미해결

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

안녕하세요 제로초님 인피니트 스크롤링 적용하는 부분에서 스크롤이 끝에 올 때마다 mainPosts가 10개씩 추가 되지 않고 한번에 50개( draft.hasMorePost = draft.mainPosts.length < 50; )가 추가 되는데 원래라면 스크롤을 끝까지 내릴 때마다 10개씩만 추가 되어야 하는 건가요? 댓글에서 SUCCESS는 한 번만 와야 된다고 하셨는데 저는 처음 한 번만 게시글이 10개 추가(success 한 번)되고 이후에는 게시글이 50개가 될 때까지 한꺼번에 success가 들어옵니다 콘솔에 inView를 찍어보니 처음 10개만 들어왔을 때는 true -> false로 값의 변화가 있는데 한번에 success 되는 부분에서의 inView의 값은 계속 true로 찍힙니다.. 이런 경우에는 어떻게 해결해야 되나요..?? index.js const Home = () => { const dispatch = useDispatch(); const { me } = useSelector((state) => state.user); const { mainPosts, hasMorePost, loadPostsLoading } = useSelector((state) => state.post); const [ref, inView] = useInView(); useEffect( () => { dispatch({ type: LOAD_POSTS_REQUEST, }); }, []); useEffect( () => { if (inView && hasMorePost && !loadPostsLoading) { const lastId = mainPosts[mainPosts.length - 1]?.id; dispatch({ type: LOAD_POSTS_REQUEST, lastId, }); } }, [inView, hasMorePost, loadPostsLoading, mainPosts], ); return ( <AppLayout> {me && <PostForm />} {mainPosts.map((post) => <PostCard key={post.id} post={post} />)} <div ref={hasMorePost && !loadPostsLoading ? ref : undefined} style={{ height: 10, backgroundColor: 'red' }} /> </AppLayout> );

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

npm start 안됨

해결됨

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

다른 폴더에서 연습하다가 다시 강의할때 만든 폴더를 로컬 서버에 연결하려고 하니 안되네요 npm start하면next build 하라고 나오고 그대로 하면 또 다른 에러가 떠서 에러 동굴로 들어가는 느낌이에요 다른 폴더는 또 로컬서버 3000으로는 들어가지는데 코드 변경한게 저장해도 반영이 안되고 예전 모습 그대로만 나와요 구글링 해보면 도커를 설치해서 설정 추가하라고 나오는데 이렇게 따라해볼까요?? 구글에서 하라는대로 하다가 모두 엉망진창이 될까봐 두려워요

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

function 컴포넌트 생명주기 관련해서 질문있습니다.

해결됨

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

안녕하세요. Section10 함수형 컴포넌트의 생명주기에서 궁금한 점이 있어 질문 드립니다. component가 unmount 되는 상황을 만들기 위해 router.push로 페이지를 이동하잖아요? 그런데 router.push 로 이동할 때는 return()=>{...} 의 내용이 제대로 실행되는데, 주소창에 직접 이동할 주소를 써서 이동했을 때 에는 같은 동작이 실행되지 않더라구요. 둘다 현재 컴포넌트가 제거되고 새로운 컴포넌트가 화면에 나타나는 것아닌가요? 다르게 동작하는데 이유가 있는지, 아니면 제가 코드를 잘못 쓴건지 피드백 부탁드립니다. 감사합니다! 작성코드 useEffect(() => { console.log('컴포넌트가 마운트됐습니다~'); return () => { alert('컴포넌트가 제거됩니다~'); }; }, []); useEffect(() => { console.log('컴포넌트가 변경됐습니다~'); }); const onClickButton = () => { setCount((prev) => prev + 1); }; const onClickMove = () => { router.push('/'); };

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

_app.tsx import 에러

해결됨

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

안녕하세요 강사님, 강의 잘 듣고 있습니다. 혹시 다음과 같은 에러가 발생하는데 뭘 잘못한지 모르겠어서 문의 남깁니다. 아래 사진 파일들은 순서대로 _app.tsx .eslintrc.js .eslintrc.json package.json 입니다. 감사합니다!

  • react
  • node.js
  • seo
  • graphql
  • next.js
김재은 댓글 1 좋아요 0 조회수 359

게시글 좋아요 부분 강의에서 하트색이 바로 변하지 않습니다

미해결

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

에러는 없고 데이터에서도 like하고 unlike가 잘되는건 확인했는데 화면에서는 새로고침 해야지만 바뀌네요 그리고 좋아요하고 다시 눌러서 취소 할려는데 취소가 안되고 계속 중복으로 좋아요가 됩니다 const express = require("express"); const { Post, Image, Comment, User } = require("../models"); const { isLoggedIn } = require("./middlewares"); const router = express.Router(); router.post("/", isLoggedIn, async (req, res, next) => { try { const post = await Post.create({ content: req.body.content, userId: req.user.id, }); 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) => { try { const post = await Post.findOne({ where: { id: req.params.postId }, }); if (!post) { return res.status(403).send("존재하지 않는 게시글입니다"); //return을 붙여줘야지 send하고 밑에 json이 동시에 실행안됨 } const comment = await Comment.create({ content: req.body.content, PostId: req.params.postId, 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) => { 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) => { 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("/", (req, res) => { res.json({}); }); module.exports = router; const express = require("express"); const { Post, Image, User, Comment } = require("../models"); const router = express.Router(); router.get("/", async (req, res, next) => { try { const posts = await Post.findAll({ limit: 10, order: [ ["createdAt", "DESC"], [Comment, "createdAt", "DESC"], ], //옵션 = ASC: 오름차순 include: [ { model: User, attributes: ["id", "nickname"], //아이디 ,닉네임만 가져오기 }, { model: Image, }, { model: Comment, include: [ { model: User, attributes: ["id", "nickname"], }, ], }, { model: User, // 좋아요 누른 사람 as: "Likers", attributes: ["id"], }, ], }); res.status(200).json(posts); } catch (error) { console.error(error); next(error); } }); module.exports = router; import { Card, Button, Avatar, Popover, List, Comment } from "antd"; import { RetweetOutlined, HeartOutlined, MessageOutlined, HeartTwoTone, EllipsisOutlined, } from "@ant-design/icons"; import { useDispatch, useSelector } from "react-redux"; import PropTypes from "prop-types"; import PostImages from "./PostImages"; import { useCallback, useEffect, useState } from "react"; import CommentForm from "./CommentForm"; import PostCardContent from "./PostCardContent"; import FollowButton from "./FollowButton"; import { REMOVE_POST_REQUEST, LIKE_POST_REQUEST, UNLIKE_POST_REQUEST, } from "../reducers/post"; const PostCard = ({ post }) => { const dispatch = useDispatch(); const { removePostLoading } = useSelector((state) => state.post); const [commentFormOpened, setCommentFormOpened] = useState(false); const id = useSelector((state) => state.user.me?.id); const onLike = useCallback(() => { if (!id) { return alert("로그인이 필요합니다."); } dispatch({ type: LIKE_POST_REQUEST, data: post.id, }); }, [id]); const onUnLike = useCallback(() => { if (!id) { return alert("로그인이 필요합니다."); } dispatch({ type: UNLIKE_POST_REQUEST, data: post.id, }); }, [id]); const onToggleComment = useCallback(() => { setCommentFormOpened((prev) => !prev); }, []); const onRemovePost = useCallback(() => { dispatch({ type: REMOVE_POST_REQUEST, data: post.id, }); }, []); const liked = post.Likers.find((v) => v.id === id); console.log("@@@", liked); return ( <div style={{ marginBottom: 10 }}> <Card cover={post.Images[0] && <PostImages images={post.Images} />} actions={[ <RetweetOutlined key="retweet" />, liked ? ( <HeartTwoTone twoToneColor="#eb2f96" key="heart" onClick={onUnLike} /> ) : ( <HeartOutlined key="heart" onClick={onLike} /> ), <MessageOutlined key="message" onClick={onToggleComment} />, <Popover key="more" content={ <Button.Group> {id && post.user?.id === id ? ( <> <Button>수정</Button> <Button type="danger" onClick={onRemovePost} loading={removePostLoading} > 삭제 </Button> </> ) : ( <Button>신고</Button> )} </Button.Group> } > <EllipsisOutlined /> </Popover>, ]} extra={id && <FollowButton post={post} />} > <Card.Meta avatar={<Avatar>{post.user?.nickname[0]}</Avatar>} title={post.user?.nickname} description={<PostCardContent postData={post.content} />} /> </Card> {commentFormOpened && ( <div> <CommentForm post={post} /> <List header={`${post.Comments.length}개의 댓글`} itemLayout="horizontal" dataSource={post.Comments} renderItem={(item) => ( <li> <Comment author={item.user?.nickname} avatar={<Avatar>{item.user?.nickname[0]}</Avatar>} content={item.content} /> </li> )} /> </div> )} </div> ); }; PostCard.propTypes = { post: PropTypes.shape({ id: PropTypes.number, user: PropTypes.object, content: PropTypes.string, createdAt: PropTypes.string, Comment: PropTypes.arrayOf(PropTypes.object), Images: PropTypes.arrayOf(PropTypes.object), Likers: PropTypes.arrayOf(PropTypes.object), }).isRequired, }; export default PostCard;

  • react
  • redux
  • node.js
  • express
  • next.js
장산 댓글 1 좋아요 0 조회수 569

join과 join fetch 의 차이 ..

미해결

실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화

OrderQueryRepository 에 findAllByDto_flat 보면 다 join 으로 되어있는데 join과 join fetch (페치 조인)의 차이점은 뭔가요 ..? join도 lazy 로 되어있는거 한번에 끌고오는 건 비슷한 거 같은데 .. ㅜ

  • java
  • spring
  • spring-boot
  • jpa
김김 댓글 1 좋아요 0 조회수 657

댓글을 달면 500에러가 뜹니다

미해결

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

로그인 후 게시물에 댓글을 달면 500에러가 뜨면서 실패합니다 ㅠㅠ 백엔드에는 comment.comment 없다고 에러 뜨는거같은데 어디가 문제인지 잘모르겠습니다 지금까지 해본건 오타 찾아보고 대소문자를 바꿔보고 했는데도 안되서 결국에 질문하네요 ㅠㅠ const express = require("express"); const { Post, Image, Comment, User } = require("../models"); const { isLoggedIn } = require("./middlewares"); const router = express.Router(); router.post("/", isLoggedIn, async (req, res, next) => { try { const post = await Post.create({ content: req.body.content, userId: req.user.id, }); 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) => { try { const post = await Post.findOne({ where: { id: req.params.postId }, }); if (!post) { return res.status(403).send("존재하지 않는 게시글입니다"); //return을 붙여줘야지 send하고 밑에 json이 동시에 실행안됨 } const comment = await Comment.create({ content: req.body.content, PostId: req.params.postId, 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.delete("/", (req, res) => { res.json({}); }); module.exports = router;

  • react
  • redux
  • node.js
  • express
  • next.js
장산 댓글 1 좋아요 0 조회수 367

강의를 듣다가 export default function () 관련 궁금점이 있습니다.

해결됨

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

안녕하세요 멘토님. 항상 강의 잘 보고 있습니다. 예전부터 문의드리려다가 자꾸 잊어먹던게 있었는데 이제서야 질문드립니다. export default function aaa() { const bbb = () => { ... } ... } 위와 같이 강의를 들을 때 마다 왜 컴포넌트 부분의 최초 함수 선언 부분만 화살표 함수가 아닌 일반 함수 선언 방식으로 하시는지, 특별한 이유가 있는 것인지 궁금합니다. 감사합니다.

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

9분 05초 author이랑 isbn

미해결

실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화

author이랑 isbn이 null로 나와있는데 싱글테이블에서 Album이랑 Movie에 관련된 컬럼은 안나오고 딱 Book이랑만 관련된 author이랑 isbn 만 null로 표시됐는데 이건 JPA가 Book인 걸 알아서 그것만 표시해주는건가요 ?? 어떻게 author이랑 isbn만 표시해주게 되는건지 궁금합니다 ..

  • java
  • spring
  • spring-boot
  • jpa
김김 댓글 2 좋아요 0 조회수 532

useMemo 질문이요

미해결

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

const TextAreaStyle = { resize: 'none', height: 120, marginBotton: 5, }; function EditPostCard() { return ( <> <TextArea rows={4} style={TextAreaStyle} /> <Space wrap> <Button type="primary">수정</Button> <Button type="primary" danger>취소</Button> </Space> </> ); } export default EditPostCard; 컴포넌트 밖에서 스타일객체를 선언한 경우 function EditPostCard() { const TextAreaStyle = useMemo(() => ({ resize: 'none', height: 120, marginBotton: 5, })); return ( <> <TextArea rows={4} style={TextAreaStyle} /> <Space wrap> <Button type="primary">수정</Button> <Button type="primary" danger>취소</Button> </Space> </> ); } 컴포넌트 안에서 useMemo를 사용한 경우 리렌더링때문에 스타일을 따로 선언해주었는데요. 두 가지 경우가 큰 차이가 있나요? useMemo안 쓰고 컴포넌트 밖에다 선언해줘도 상관없나요?

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

글작성시 userId가 데이터에 저장을 안해서 게시글을 가져올려고 해도 안가져와집니다.

미해결

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

1. 뭔가 프론트는 문제가 없는거같은데 백에서는 어디에서 문제가 있는지 잘모르겠습니다 ㅠㅠ 에러는 없습니다 3. const express = require("express"); const { Post, Image, Comment, User } = require("../models"); const { isLoggedIn } = require("./middlewares"); const router = express.Router(); router.post("/", isLoggedIn, async (req, res) => { try { const post = await Post.create({ content: req.body.content, UserId: req.user.id, }); 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) => { try { const post = await Post.findOne({ where: { id: req.params.postId }, }); if (!post) { return res.status(403).send("존재하지 않는 게시글입니다"); //return을 붙여줘야지 send하고 밑에 json이 동시에 실행안됨 } const comment = await Comment.create({ content: req.body.content, PostId: req.params.postId, UserId: req.user.id, }); res.status(201).json(comment); } catch (error) { console.error(error); next(error); } }); router.delete("/", (req, res) => { res.json({}); }); module.exports = router; import { Form, Input, Button } from "antd"; import { useCallback, useRef, useEffect, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import { ADD_POST_REQUEST } from "../reducers/post"; import useInput from "./hooks/useInput"; const PostForm = () => { const { imagePaths, addPostDone, addPostLoading } = useSelector( (state) => state.post ); const [text, setText] = useState(""); const dispatch = useDispatch(); const imageInput = useRef(); useEffect(() => { if (addPostDone) { setText(""); } }, [addPostDone]); const onSubmitForm = useCallback(() => { dispatch({ type: ADD_POST_REQUEST, data: text, }); }, [text]); const onChangeText = useCallback((e) => { setText(e.target.value); }, []); const onClickImageUpload = useCallback(() => { imageInput.current.click(); }, [imageInput.current]); return ( <Form style={{ margin: "10px 0 20px" }} encType="multipart/form-data" onFinish={onSubmitForm} > <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" loading={addPostLoading} > 짹쨱 </Button> </div> <div> {imagePaths.map((v) => ( <div key={v} style={{ display: "inline-block" }}> <img src={v} style={{ width: "200px" }} alt={v} /> <div> <Button>제거</Button> </div> </div> ))} </div> </Form> ); }; export default PostForm; //saga - AddPost function addPostAPI(data) { return axios.post("/post", { content: data }); } function* addPost(action) { try { const result = yield call(addPostAPI, action.data); yield put({ //put : dispatch type: ADD_POST_SUCCESS, data: result.data, }); yield put({ type: ADD_POST_TO_ME, data: result.data.id, }); } catch (err) { yield put({ type: ADD_POST_FAILURE, data: err.response.data, }); } } // reducer 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); break; case ADD_POST_FAILURE: draft.addPostLoading = false; draft.addPostError = action.error; break;

  • react
  • redux
  • node.js
  • express
  • next.js
장산 댓글 1 좋아요 0 조회수 438

수강 범위에 대한 질문입니다 ㅠㅠㅠ

미해결

나도코딩의 자바 기본편 - 풀코스 (20시간)

안녕하세요 나도코딩님 오늘도 열심히 공부중인 학생입니다 ㅠㅠㅠ 복수전공 과목 중 자바로 배우는 자료구조를 수강중인데 사전에 자바 공부도 없이 듣는 수업이라 도통 무슨 소린지 이해가 가질 않네요.. 그래서 현재 고급편 결제하고 섹션9 추상클래스 까지 들은 상태인데 뒤로 갈수록 내용이 어려워져서 복습한다고 속도가 너무 늦어지는 상태에요.. 자료구조 내용을 이해하려면 일단 어떤 파트를 필수적으로 빨리 들어야 하고 어떤 파트는 빼도 되는지 알려주실 수 있을까요??ㅜ 답변 주시는데 도움이 될 지 모르겠지만 교재 한 챕터에 {자바 데이터 타입(기본타입, 참조타입), 제어문(조건문,반복문), 메소드(호출문,메인), try문} 이렇게만 존재하긴 하는데 중간중간 책에는 없는 추상클래스, 입력문 같은 파트도 보여서 감이 안잡히네요..

  • java
  • 객체지향
댓글 1 좋아요 1 조회수 411

ec2 에러

미해결

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

프론트서버를 ec2 에서 npm start를 하면 자꾸 client_loop: send disconnect: connection reset by peer 이라는 에러가 나오는데 해결방법이 있을까요 구글링도 해봤지만 해답을 찾지 못했습니다

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

인터페이스 변수

미해결

나도코딩의 자바 기본편 - 풀코스 (20시간)

안녕하세요~ 강사님, 인터페이스(후반전) 강의를 듣고 있는데, 왜 인터페이스 변수를 만드는지 이해가 가지 않습니다. 수업 내용에서 FactoryCam이 인터페이스 Detectable과 Reportable을 구현하여 인터페이스에 있는 메소드를 FacstoryCam에서 구현해야한다는 것은 이해했습니다. 그리고 다른 클래스의 detect 메소드와 report 메소드를 호출하는것이라서 public void detect(){detecter.detect();} 이고, detecter은 객체이잖아요. 여기서 막힙니다. 이 객체랑 인터페이스 변수랑 무슨 상관인지? FactoryCam 의 인터페이스 변수를 생성해서 변수에 값 저장하는 걸로 하면 되지 않는지? 왜 인터페이스 변수를 선언해서 거기다가 값을 저장하는지, 잘 이해가 안 됩니다.... ㅠㅠ 그리고 추가로, 인터페이스로 다중 상속이 가능하다고 하셨는데, 수업 내용 중 어떤 것이 다중 상속이 되고 있는지 파악하기가 어렵습니다. 혹시, 다른 클래스의 메소드를 호출할 수 있는 부분때문에 다중 상속이 가능한 것인가요? 후반부로 갈수록 어렵네요 ㅠㅠ

  • java
  • 객체지향
vlrmffpt33 댓글 1 좋아요 0 조회수 497

OAuth 관련 질문이 있습니다.

해결됨

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

안녕하세요 멘토님, 항상 틈틈히 강의 잘 보고 있습니다. 질문부터 말씀드리자면, OAuth로 로그인 기능을 만들면 백엔드에서 별도로 JWT관련 인증, 발급, 재발급 등의 로직을 개발해주지 않아도 되는지 궁금해서 질문을 드리게 되었습니다. 제 상황을 말씀드리자면 토이프로젝트 개발을 슬슬 시작하려는데요, 시작하기에 앞서 백엔드 서버부터 먼저 만들고 있었습니다. 해당 강의에서 제공해주는 백엔드 서버의 중고마켓이나 게시판 API를 활용한 것이 아닌, 다른 주제로 개인 토이프로젝트를 새로 프론트부터 백엔드단까지 직접 만들어보려고 합니다. 기존 웹 개발 경력이 조금 있어서인지 자바나 노드 백엔드 구축 등을 배워서 API를 개발하는 것은 할만했습니다. 하지만 백엔드에서 딱 하나, JWT 관련 로직을 추가하는 부분이 제 기준으로 너무 어렵고 벽이더라구요. (현업에서도 JWT 경험이 없습니다) 그래서 시간이 너무 걸려서 보류해두었다가 다시 강의를 듣고 있었는데 이번 강의에서 OAuth 관련 내용을 보게 되었습니다. 더 찾아보니까 인증, 발급과 같은 각종 로그인 관련 기능들을 해당 OAuth 서버에서 제공해준다고 되어있더라구요. 그래서 해당 부분들을 활용하면 기존의 JWT 발급이나 인증 관련 로직을 백엔드에서 직접 구축해야하는 부분을 스킵하고 진행할 수 있지 않을까 궁금해져서 질문 글을 올리게 되었습니다. 강의 내용의 OAuth 부분을 보고 궁금해져서 질문을 올려야 겠다고 생각했는데 어쩌다 보니 백엔드 느낌의 질문 글이 되어 죄송합니다. 하지만 멘토님이 백엔드쪽 강의도 하시는걸로 알고 있어 혹시나 질문을 드려봅니다. 감사합니다.

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

prevState를 사용하여 리팩토링

해결됨

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

import { useState } from "react"; import { Modal } from "antd"; import { Address } from "react-daum-postcode/lib/loadPostcode"; import DaumPostcodeEmbed from "react-daum-postcode"; const ModalCustomPage = () => { const [isModalOpen, setIsModalOpen] = useState(false); const onToggleModal = () => { setIsModalOpen((prev) => !prev); }; const handleComplete = (address: Address) => { console.log("실행되었습니다."); console.log(address); onToggleModal(); }; return ( <> {isModalOpen && ( <Modal title="모달 제목" open={true} onOk={onToggleModal} onCancel={onToggleModal} > <DaumPostcodeEmbed onComplete={handleComplete} /> </Modal> )} </> ); }; export default ModalCustomPage; 안녕하세요, 한 가지 궁금증이 들어 질문합니다. onToggleModal 함수를 보면 prevState를 사용해서 isOpenModal 값을 바꾸는데 굳이 그럴 필요가 있을까? 라는 생각이 들어서요. const onToggleModal = () => { setIsModalOpen((!isModalOpen); }; onToggleModal 안에서 여러개의 setIsModalOpen이 실행되는 것이 아니기 때문에 그냥 이렇게 코드를 작성해도 함수가 끝나면 isOpenModal 값이 바뀌고 리렌더링되어 버그 없이 잘 실행될 것 같은데 혹시 다른 이유가 있나요? 아님 setState 사용할때 prevState를 사용하는 것이 암묵적인 원칙인가요?

  • react
  • node.js
  • seo
  • graphql
  • next.js
박혜주 댓글 1 좋아요 0 조회수 1199

새로고침 시 로그인 문제 + mui ssr 문제

미해결

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

안녕하세요 제로초님. getServerSideProp를 적용한 이후 새로고침 시 로그인 문제가 발생합니다. 로그인을 하고 -> 1번째 새로 고침 시 로그인이 풀립니다. 하지만 1번째 새로 고침 이후, 끈기를 가지고 계속해서 새로고침을 하다보면 로그인 상태로 다시 돌아옵니다. 보통 3번째 정도 새로고침을 하면 로그인이 돌아옵니다.. 이거는 됐다가 안됐다가 하는 문제이기 때문에 제 코드 문제는 아닌 거 같습니다.. 새로고침을 n번째 시도 했을 때 로그인이 불규칙 하게 돌아옵니다. 그리고 mui ssr 문제도 있는데요. styled-components는 _document와 babelrc? 를 적용하지 않아도 잘 적용되는 반면에, mui ssr은 https://github.com/mui/material-ui/issues/33072 여기에서 시키는 대로 해봐도 적용이 안 되네요 1번째 사진은 새로고침 해서 ssr이 적용된 스타일 입니다. 2번째 사진은 /profile 페이지 갔다가, 왼쪽 상단 mui 눌러서 홈페이지로 이동 했을때 csr이 적용된 스타일 (= 원래 디자인) 입니다. 혹시 짚이는 게 있으시면 답변 부탁드릴게요.. 감사합니다.

  • react
  • redux
  • node.js
  • express
  • next.js
신영 유 댓글 1 좋아요 0 조회수 629

graphql의 DOCS가 강의와 다른 것 같아요.

해결됨

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

섹션 6 포트폴리오 리뷰 영상 보면서 따라하고 있는데 아무래도 createBoard의 파라미터랑 리턴값이 강의와 다른 것 같아서 오류가 발생하는 것 같은데 어떻게 해야 같은 API를 사용할 수 있을까요?

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

강사님 좋은강의 만들어 주셔서 감사합니다.

미해결

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

하루에 한강의씩 들었더니 어느덧 배포까지 완강 하였네요. 알차고 좋은강의 만들어 주셔서 감사합니다.

  • react
  • node.js
  • postgresql
  • docker
  • typescript
  • 클론코딩
  • next.js
rhkdtjd_12 댓글 1 좋아요 1 조회수 374

인기 태그

인프런 TOP Writers

주간 인기글