25%
66,000원
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
npx sequelize db:create 에러
npx sequelize db:create 했을 때 다음과 같은 에러가 발생합니다. 개인적으로 진행하고 있는 프로젝트에 적용하며 따라하는 중이라서 프로젝트의 내용은 제로초님과 똑같지는 않지만, 설정은 모두 동일하게 진행했습니다.아래 사진은 config/config.js 입니다. 에러 메시지를 아무리 검색해봐도 모르겠어서.. 도와주시면 감사하겠습니다ㅜㅜ
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
질문드립니다..
에러를 찾으면서 여러가지 계속 시도해도 도저히 방법이 없어서 질문드립니다.. passport로 login까지는 성공하였고 logout에서 서버에서 에러가나는데요 에러내용은 req.logout()에 콜백함수가 필요하다는것 같은데 뭘 해도 안되네요.. router의 순서도 login다음 logout입니다 logout network 로그인성공 뭐가 문제일까요..?
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
mutate 질문입니다!
import React, { useEffect, useState, useCallback } from 'react'; import Head from 'next/head'; import { useSelector } from 'react-redux'; import Router from 'next/router'; import { END } from 'redux-saga'; import axios from 'axios'; import useSWR from 'swr'; import AppLayout from '../components/AppLayout'; import NicknameEditForm from '../components/NicknameEditForm'; import FollowList from '../components/FollowList'; import { LOAD_MY_INFO_REQUEST } from '../reducers/user'; import wrapper from '../store/configureStore'; import { backUrl } from '../config/config'; const fetcher = (url) => axios.get(url, { withCredentials: true }).then(result => result.data); const Profile = () => { const { me } = useSelector((state) => state.user); const [followersLimit, setFollowersLimit] = useState(3); const [followingsLimit, setFollowingsLimit] = useState(3); // 팔로워, 팔로잉 불러오기 const { data: followersData, error: followerError, mutate: mutateFollower } = useSWR(`${backUrl}/user/followers?limit=${followersLimit}`, fetcher); const { data: followingsData, error: followingError, mutate: mutateFollowing } = useSWR(`${backUrl}/user/followings?limit=${followingsLimit}`, fetcher); useEffect(() => { if (!(me && me.id)) { Router.replace('/'); } }, [me && me.id]); const loadMoreFollowings = useCallback(() => { setFollowingsLimit((prev) => prev + 3); }, []); const loadMoreFollowers = useCallback(() => { setFollowersLimit((prev) => prev + 3); }, []); if (!me) { return '내 정보 로딩중...'; } // 주의: return이 hooks보다 위에 있으면 안됨 if (followerError || followingError) { console.error(followerError, followingError); return <div>팔로잉/팔로워 로딩 중 에러가 발생합니다.</div> } return ( <> <Head> <title>내 프로필 | NodeBird</title> </Head> <AppLayout> <NicknameEditForm /> <FollowList header="팔로잉" data={followingsData} onClickMore={loadMoreFollowings} loading={!followingsData && !followingError} mutateFollowing={mutateFollowing} /> <FollowList header="팔로워" data={followersData} onClickMore={loadMoreFollowers} loading={!followersData && !followerError} mutateFollower={mutateFollower} /> </AppLayout> </> ); }; export const getServerSideProps = wrapper.getServerSideProps(store => async ({ req }) => { console.log('getServerSideProps start'); const cookie = req ? req.headers.cookie : ''; axios.defaults.headers.Cookie = ''; if (req && cookie) { axios.defaults.headers.Cookie = cookie; } store.dispatch({ type: LOAD_MY_INFO_REQUEST, }); store.dispatch(END); console.log('getServerSideProps end'); await store.sagaTask.toPromise(); }); export default Profile; import React from 'react'; import propTypes from 'prop-types'; import { Button, List, Card } from 'antd'; import { StopOutlined } from '@ant-design/icons'; import { useDispatch } from 'react-redux'; import { UNFOLLOW_REQUEST, REMOVE_FOLLOWER_REQUEST } from '../reducers/user'; const FollowList = ({ header, data, onClickMore, loading, mutateFollowing, mutateFollower }) => { const dispatch = useDispatch(); const onCancel = (id) => () => { if (header === '팔로잉') { dispatch({ type: UNFOLLOW_REQUEST, data: id, }); setTimeout(() => { mutateFollowing((prev) => prev.filter((data) => data.id !== id)); }, 500); } else { dispatch({ type: REMOVE_FOLLOWER_REQUEST, data: id, }); setTimeout(() => { mutateFollower((prev) => prev.filter((data) => data.id !== id)); }, 500); } }; return ( <List style={{ marginBottom: 20 }} grid={{ gutter: 4, xs: 3, md: 4 }} size="small" header={<div>{header}</div>} loadMore={<div style={{ textAlign: 'center', margin: '10px 0' }}><Button onClick={onClickMore} loading={loading}>더 보기</Button></div>} bordered dataSource={data} renderItem={(item) => ( <List.Item style={{ marginTop: '20px' }}> <Card actions={[<StopOutlined key="stop" onClick={onCancel(item.id)} />]}> <Card.Meta description={item.nickname} /> </Card> </List.Item> )} /> ); }; FollowList.propTypes = { header: propTypes.string.isRequired, data: propTypes.array.isRequired, }; export default FollowList; 팔로잉 취소나 팔로워 삭제 시키는 버튼 클릭했을 때 dispatch 실행 이후 DB에서 삭제되기 전에 mutateFollower, mutateFollowing이 실행할 수 있어 해당 팔로잉, 팔로워 사용자 삭제했는데 화면에서 새로고침 전까지 안없어지더라구요 그래서 setTimeout을 사용했는데 다른 방법도 있을까해서 여쭤봅니다! setTimeout으로 사용하기도 하나요?
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
sequelize 모델 정의 질문
안녕하세요. 강의를 다시 보다가 다른 부분이 있어서 질문 드립니다. 전에 강의를 볼땐 sequelize 모델 정의에서 module.exports class Comment extends Model { static init(sequelize) return spuer.init } 이런식으로 정의했다면 지금 다시 볼때는 module.exports = (sequelize, DataTypes) => { const Comment = sequelize.define() } 으로 정의하는데 define으로 하는것이 최신인가요? 공식문서에서는 define이 처음으로 소개되긴하던데.. 밑에 글보면 class가 최신이라고 하신것같은데 영상에서는 왜 define으로 나오는지..
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
git clone 에러
git clone할때 위와같이 -bash: git: command not found가 뜹니다. git, bash설치 되어있는데 왜저렇게 뜨는걸까요?
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
백엔드서버 500 에러 발생
안녕하세요 제로초님! 강의 잘 수강하고 있습니다. 밑에 다른 분과 같은 에러가 발생하여 질문 남깁니다. 프론트, 백엔드 서버는 작동이 되긴 하는데 프론트 회원가입 페이지에서 가입하기 버튼 누를 시 이러한 에러가 발생합니다. 밑 글에서 제로초님이 답글 달아주신 것처럼 우선, mysql 비밀번호는 정확하게 입력한 상태이며 우분투 back 경로에서 vim .env 하였을때 DB 패스워드도 일치하였습니다. 터미널에서 다시 mysql 비밀번호가 맞는지 확인 후, 로컬 back 경로에서 npx sequelize db:create 를 실행하고, 서버 새로고침을 하였는데도 같은 현상이 발생합니다. 혹시 제가 시도했던 방법 중 틀린 부분이나 추가로 확인 및 진행해봐야할 부분이 있을까요?
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
에러...
강사님 아래처럼 이런 에러가 뜨는데요.. ㅜ
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
generateDummyPost 부분 질문드립니다.
안녕하세요 제로초님, generateDummyPost 함수를 만들어서 더미데이터를 만드는 부분의 코드에서 질문이 있습니다. 강의와 깃에 올라온 코드는 인자로 ( number )를 받아와서 바로 Array(number)로 시작하는 코드인데요. 저는 그렇게 코드를 짜게 되면 반환값이 undefined가 됩니다. 그래서 코드를 위 스크린샷처럼 number를 받아 만든 Array를 변수에 담아서 그 변수를 반환하도록 변경했는데요. 문제없이 잘 실행은 되는데 강의나 깃에 올려진 코드를 썼을 때는 오류가 나는 이유가 무언가 사용 방법이 바뀌어서 인지, 아니면 제가 놓친 부분이 있는 지 궁금합니다.
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
typescript SSR Cookie
타타이스크립트로 작성하는 도중에 Cookie에 속성이 없다고 나옵니다. 젝제가 생각하기에는 HeadersDefaults에 Cookie가 없어서 이런 오류가 나온다고 생각합니다. 이런 경우에는 어떻게 해야 하나요?
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
git pull관련 에러입니다.
처음에는 git pull이 됐었는데, 어떤 이유에선지 이런 에러가 발생했습니다. (fatal: unsafe repository...) 커맨드 창에 나온 대로 git config --gloabl --add safe..를 쳤는데 해결이 되지 않아서 어떻게 하면 될지 모르겠습니다 ㅜ
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
쿠키까지 잘 받아오는데 SSR 적용오류 질문 드립니다
자주 질문 드려서 죄송합니다.. 다름이 아니라 쿠키 까지 받아오는 부분 확인하고 새로고침 눌렀을 때 화면이 계속 새로고침이 되서 쿠키 전부 삭제하고 제부팅후에 다시 켜보니 saga LOAD_MY_INFO에서 data undefined 랑 백에서는 [err_http_invalid_header_value]: invalid value "undefined" for header "cookie" 가 떳었는데 export const getServerSideProps = wrapper.getServerSideProps( async (context) => { console.log("getServerSideProps start"); console.log(context.req.headers); const cookie = context.req ? context.req.headers.cookie : ""; axios.defaults.headers.Cookie = ""; if (context.req && cookie) { axios.defaults.headers.Cookie = cookie; } context.store.dispatch({ type: LOAD_MY_INFO_REQUEST, }); context.store.dispatch({ type: LOAD_POSTS_REQUEST, }); context.store.dispatch(END); console.log("getServerSideProps end"); await context.store.sagaTask.toPromise(); } ); 이 부분을 제로초님 깃허브에서 복붙하고 나서는 오류는 없어졌으나 처음 상태처럼 새로고침시 SSR적용이 안돼서 질문을 드립니다 ㅠㅠ
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
getServerSideProps에서 store를 사용하는 것에 문제가 있습니다.
기본적으로 모든 페이지에서 유저 정보를 가져와 redux에 있는 isLogin state를 true로 만들어 로그인 상태를 유지하고 있습니다. 그 상태에서 개인 페이지로 이동하는데, 이 때 개인 페이지는 먼저 getServerSideProps에서 store에 있는 isLogin 값을 확인하여 로그인 한 상태일 때만 접속을 허용하고 아니면 redirect 합니다. 그런데 문제는 이전 페이지에서 유저 정보를 받아와 isLogin이 true 임에도, Link를 통해 개인 페이지로 이동하면 getServerSideProps에서는 여전히 isLogin이 false라 redirect 됩니다. 세팅은 강좌와 똑같이 했고, dispatch는 잘됩니다. 다른 페이지에서도 store를 이용하려 할 때 문제가 생기는 걸 보니, getServerSideProps안의 store는 client와 다르게 여전히 initialState인 것 같습니다. 어떤 것이 문제일지, 혹은 리다이렉트 시키는 다른 더 좋은 방법이 있는지 궁금합니다. getServerSideProps에서 또 다시 유저 정보를 가져와서 state를 반영한 뒤 store를 확인해야 하는 것일까요?
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
SQL 친구 테이블
제로초님 SQL 친구 테이블을 만들고있는데, userId, friendId 이렇게 PK키 두개 잡고 Friend Table을 따로 만들어 주는게 가장 좋은 방법일까요? 이렇게 되면 중복이 생기는데 (예를들면 userId 123, friendId789 생성시 friendId 789, userId 123 동시 생성) 뭔가 중복때문에 이게 최선인가 싶은데, 이것보다 더 좋은방법이 있는지 조언을 여쭙고싶습니다!
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
혹시 nextJS 는 Node가 설치된 프론트엔드 서버가 설치되어있어야만 사용가능한가요?
저는 아파치/php 를 사용하고있습니다! 일반 리액트는 build 를 하면 build 폴더가 생성되어 서버가 어떤 것이든 폴더만 업로드하면, 사용이 가능했는데, nextJS 는 build 폴더가 생성이 안되고 서버컴퓨터에서 npm build 후, npm start 명령어를 실행해야만 실행이 되는 것 같더라구요. 즉, 우분투 제어가 가능한(node 설치 및 명령어 실행 가능) 클라우드 서버만 사용이 가능한가요?
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
로그아웃 에러 질문있습니다
안녕하세요 제로초님 강의 잘 듣고있습니다. 지금 로그인은 되는데 로그아웃을 누르면 TypeError: req.logout is not a function 뜨면서 진행이 되질 않는데의심이 되는 부분은 로그인시에 response headers에 setcookie가 없다는 점이로그아웃 할 때 문제가 되는 부분일까요?..
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
서버에서 서버 쿠키 공유 질문입니다!
1분 54초 쯤에 프론트 서버(3060)와 노드 서버(3065)의 도메인이 달라 쿠키가 전달이 안된다고 설명하시고 계시는데 서버에서 서버로는 쿠키 문제 없이 전달된다고 하시지 않았나 싶어서 여쭤봐요! 지금 문제는 이후에 설명하시는 '프론트 서버는 브라우저처럼 쿠키를 자동으로 담아서 보내지 않기 때문에 발생하는 문제' 아닌가요?
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
cookie 공유 질문이요
export const getServerSideProps = wrapper.getServerSideProps( async (context) => { const cookie = context.req ? context.req.headers.cookie : ""; axios.defaults.headers.Cookie = ""; if (context.req && cookie) { axios.defaults.headers.Cookie = cookie; } context.store.dispatch({ type: LOAD_MY_INFO_REQUEST, }); context.store.dispatch({ type: LOAD_POSTS_REQUEST, }); context.store.dispatch(END); await context.store.sagaTask.toPromise(); } ); 여기서 쿠키공유를 막기위해 if (context.req && cookie) { axios.defaults.headers.Cookie = cookie; } 를 넣어주셨는데 이 조건문없이 export const getServerSideProps = wrapper.getServerSideProps( async (context) => { const cookie = context.req ? context.req.headers.cookie : ""; axios.defaults.headers.Cookie = cookie; context.store.dispatch({ type: LOAD_MY_INFO_REQUEST, }); context.store.dispatch({ type: LOAD_POSTS_REQUEST, }); context.store.dispatch(END); await context.store.sagaTask.toPromise(); } ); 이런식으로 해도 페이지 접속하는 유저마다 cookie가 달라서 변수 cookie는 계속 변하고 axios.defaults.headers.Cookie = cookie; 값이 계속 달라져서 문제가 없을 거 같은데 어떻게 쿠키가 공유 되는건가요?
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
Pem(키페어) 파일을 다른 컴퓨터에서 사용할 경우 질문입니다.
안녕하세요 제로초님. 개인적으로 포트폴리오 사이트를 만드는 중입니다. 궁금한것이 현재 강좌까지 진행 했다는 가정하에 git clone, 코드를 수정해서 깃헙에 commit, push도 하고, ssh 접속 및 ubuntu 경로에서도 git pull 등 전반적인 작업을 두 컴퓨터에서 진행하고 싶습니다. git clone을 한 상태여서 pem(키페어) 파일 같은 경우는 git.ignore로 인해서 clone을 해도 pem 파일은 없는 상태여서 ssh 접속을 못하는 상태입니다. pem 파일안에 들어있는 코드를 복사해서 다른 컴퓨터에 pem 파일을 만든 뒤 복사한 코드를 붙여넣기 해도 ssh 접속이 가능할까요? 개인 사정 상 두개의 컴퓨터에서 작업을 진행해야 해서요!
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
시퀄라이즈 질문입니다!
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'], }] }); 노드 서버에서 fullPost를 보내주는데 이때 게시글 작성자는 User 이름으로 좋아요나 댓글 작성자는 Likers, Comments 이름으로 보내지는 것으로 확인되는데 이게 User는 무조건 로우가 하나인 객체 값을 가지고 Likers, Comments는 배열로 객체 요소를 여러 개 가져서 시퀄라이즈에서 자동으로 's'를 붙여서 보내는 식으로 이해하면 될까요?? p.s. 질문하면서 생각이 난건데 시퀄라이즈에서 관계를 정의할 때 Post는 User(게시글 작성자)에 대해 belongsTo이고,Likers, Comments, Images 같은 경우는 belongsToMany이거나 hasMany이기 때문에 시퀄라이즈에서 's'를 붙여서 보내고 배열 형태로 객체 요소들을 넣어서 보내는 것이라고 이해하면 될까요? 아래 mainPosts 요소 하나 올립니다!
- 미해결[리뉴얼] React로 NodeBird SNS 만들기
비로그인 상태에서 댓글 입력하면 댓글폼 개수만큼 alert가 발생합니다!
import React, { useCallback, useEffect } from 'react'; import PropTypes from 'prop-types'; import { Form, Input, Button } from 'antd'; import { useDispatch, useSelector } from 'react-redux'; import useInput from '../hooks/useInput'; import { ADD_COMMENT_REQUEST, ADD_COMMENT_RESET } from '../reducers/post'; const CommentForm = ({ post }) => { const dispatch = useDispatch(); const { addCommentDone, addCommentLoading, addCommentError } = useSelector((state) => state.post); const [commentText, onChangeCommentText, setCommentText] = useInput(''); useEffect(() => { if (addCommentDone) { setCommentText(''); } }, [addCommentDone]); useEffect(() => { if (addCommentError) { alert(addCommentError); dispatch({ type: ADD_COMMENT_RESET }); } }, [addCommentError]); const onSubmitComment = useCallback(() => { dispatch({ type: ADD_COMMENT_REQUEST, data: { content: commentText, postId: post.id }, }); }, [commentText]); return ( <Form onFinish={onSubmitComment}> <Form.Item style={{ position: 'relative', margin: 0 }}> <Input.TextArea value={commentText} onChange={onChangeCommentText} rows={4} /> <Button style={{ position: 'absolute', right: 0, bottom: -40, zIndex: 1 }} type="primary" htmlType="submit" loading={addCommentLoading}ß > 댓글 입력 </Button> </Form.Item> </Form> ); }; CommentForm.propTypes = { post: PropTypes.object.isRequired, }; export default CommentForm; 위 코드는 CommentForm 컴포넌트인데 비로그인 상태에서 댓글 입력 버튼을 클릭하면 ADD_COMMENT_FAILURE 액션이 실행되고 alert(addCommentError)를 알람 설정했습니다! 근데 이때 댓글폼을 세 개 열어 놓고 댓글 입력 버튼을 클릭하면 세 번 알람이 되더라구요..ㅠㅠㅠ 혹시 한 번만 알람되도록 설정하는 방법이 있을까하고 여쭤봅니다...ㅠADD_COMMENT_RESET은 그냥 addCommentError: false로 바꿔주는 것 말고는 없습니다. 그리고 이번에 라이브러리 최신화한 것 감사합니다! 강의 내용은 아니지만 다름이 아니라 intersection 폴더에서 컴포넌트들 화살표 함수에서 함수 선언식으로 바꾸셨던데 이유가 있을까요??