React로 NodeBird SNS 만들기

React로 NodeBird SNS 만들기

(9개의 수강평)

316명의 수강생
hsjo12 프로필

질문이요 hsjo12 3시간 전

시퀄라이즈 association이 제가 이해한 개념이 맞는지 확인 부탁드려요. 

 post.js

db.Post.belongsToMany(db.User, { through'Like'as'Likers' }); 

user.js

db.User.belongsToMany(db.Post, { through'Like'as'Liked' });

Post 와 User는 N:M관계로 서로 이어주는 중간테이블 Like를 갖고 있다. 

그 Like 테이블 안에는, 기본적으로 Created_at, Updated_at 컬럼을 갖고있다.

그리고, 두개의 테이블의 아이디 PostId 와 UserId를 갖고있다.

post.js 에서 정의한 Liker는 UserId 를 뜻하고, 

user.js 에서 정의한 Liked는 PostId를 뜻한다. 

서로의 아이디를 가리키는 형국이다. 

Like 중간테이블에 값저장하기. 

const post = await db.Post.findOne({ where: { id: req.params.id }});
await post.addLiker(req.user.id);

post.addLiker(req.user.id); : 중간 테이블의 값을 넣어줌

Liker 이므로 UserId를 써주어야한다.

중간 테이블에는 , post 이부분에서 PostId 와 

req.user.id 이 부분에서 UserId가 채워진다. 

1. 지금 제가 맞게 이해한건가요? 

________________________________________

2.

[ Hashtag {

    dataValues:

     { id: 9,

       name: 'ww',

       updatedAt: 2019-10-19T07:11:33.896Z,

       createdAt: 2019-10-19T07:11:33.896Z },

    _previousDataValues:

     { name: 'ww',

       id: 9,

       createdAt: 2019-10-19T07:11:33.896Z,

       updatedAt: 2019-10-19T07:11:33.896Z },

    _changed:

     { name: false, id: false, createdAt: false, updatedAt: false },

    _modelOptions:

     { timestamps: true,

       validate: {},

       freezeTableName: false,

       underscored: false,

       paranoid: false,

       rejectOnEmpty: false,

       whereCollection: [Object],

       schema: null,

       schemaDelimiter: '',

       defaultScope: {},

       scopes: {},

       indexes: [],

       name: [Object],

       omitNull: false,

       charset: 'utf8mb4',

       collate: 'utf8mb4_general_ci',

       sequelize: [Sequelize],

       hooks: {} },

    _options:

     { isNewRecord: true,

       _schema: null,

       _schemaDelimiter: '',

       attributes: undefined,

       include: undefined,

       raw: undefined,

       silent: undefined },

    isNewRecord: false } ]

지금  윗 값이
result.map(r => r[0])

이거 인데요. 

await newPost.addHashtags(result.map(r => r[0]));

Hashtags 이니 아이디들 들어간 배열을 수용할 수있는건 알겠는데요..

newPost.addHashtags( ) 이 괄호안  부분에 id 들어있는 객체(윗 값처럼 여러개 섞였어도..)만 있으면, 자기가 알아서 id 만 골라서 갖고 가는건가요?? 

_________________________________________

3.

1:N 관계에서요 

post 와 image는 1:N 관계이잖아요

db.Image.belongsTo(db.Post);

Image가 post에게 belongsTo (===속함) 하니까,

Image 테이블에 postId라는 post를 가르키는 컬럼이 생기는걸 알 수 있는데요. 

add 함수 쓸때요, 

          if (Array.isArray(req.body.image)) {
            const images = await Promise.all(req.body.image.map((image=> {
              return db.Image.create({ srcimage });
            }));
            await newPost.addImages(images);

이렇게 되어 있던데요, 

newPost.addImages(images)

에서 도대체 괄호 안에 무엇을 써주어야 할지 헷갈리네요?

newPost 는 테이블이고 

Images 도 테이블인데, 

괄호안에, postId 값을 넣어줘야한게 아닌가요?

괄호에 무엇이 들어 가야하는지 헷갈리네요. 

1번과 다르게 

괄호 안에, 중간테이블의 Liker (UserId를 가르키는 ) 채우기 위해 req.user.id 넣어 주었는데요.. 

post.addLiker(req.user.id); : 중간 테이블의 값을 넣어줌

Liker 이므로 UserId를 써주어야한다.

중간 테이블에는 , post 이부분에서 PostId 와 

req.user.id 이 부분에서 UserId가 채워진다. 

여기에서도 의문인게, 

A.addB(___) 이면, A와 B 둘다 DB 테이블이여야한는데

Liker는 테이블이 아니지 않나요.. ???

아니면, 다대다 할때만, as를 이용해서 user 테이블을 Liker라 이름 붙이고 또 동시에, UserId라는 표현으로   해주는건가요?

___________________________________________

4. 

관계를 지으면 id 부분이 와서 다른테이블을 가르키잖아요. id 대신에 따로 지정한 것이  오게 할 수 도 있나요?

___________________________________________

0
lolola 프로필

me 가없을때 0을 대신넣어주는 로직 질문 lolola 14시간 전

const user = await db.User.findOne({
      where: { id: parseInt(req.params.id10) || req.user.id || 0 }
   });
1. 이부분에서요 req.params.id가 0이면 내정보를 요청한걸로쳐서
req.user.id를찾는것은 이해하고있습니다.
근데 로직에서 req.params.id가 0이면 parseInt()가 0을 반환
하잖아요?
그럼이렇게될텐데
where:{id: 0 || req.user&&req.user.id || 0}
or연산자에 의해서 0 이 false로 처리되어서 두번째값인 req.user
가 대입되는건가요?
2. 그렇다면 req.user역시도 undefined라면 마지막값도 0이니
where:{false||false||false}가 되서 sequelize가
에러를일으키지않나요?sequelize가 undefined값을받았을때 오류를
일으킨다고 다른댓글에 답변하신거를 봐서요

1
unknown o 프로필

bcrypt 설치 오류 unknown o 1일 전

> bcrypt@3.0.6 install D:\Project\test\bb\back\node_modules\bcrypt

> node-pre-gyp install --fallback-to-build

node-pre-gyp WARN Using needle for node-pre-gyp https download 

node-pre-gyp WARN Tried to download(404): https://github.com/kelektiv/node.bcrypt.js/releases/download/v3.0.6/bcrypt_lib-v3.0.6-node-v72-win32-x64-unknown.tar.gz 

node-pre-gyp WARN Pre-built binaries not found for bcrypt@3.0.6 and node@12.3.1 (node-v72 ABI, unknown) (falling back to source compile with node-gyp) 

gyp ERR! UNCAUGHT EXCEPTION 

gyp ERR! stack Error: spawn D:\Visual Studio\MSBuild\15.0\Bin\MSBuild.exe ENOENT

gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:264:19)

gyp ERR! stack     at onErrorNT (internal/child_process.js:456:16)

gyp ERR! stack     at processTicksAndRejections (internal/process/task_queues.js:84:9)

gyp ERR! System Windows_NT 10.0.18362

gyp ERR! command "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\node_modules\\node-gyp\\bin\\node-gyp.js" "build" "--fallback-to-build" "--module=D:\\Project\\test\\bb\\back\\node_modules\\bcrypt\\lib\\binding\\bcrypt_lib.node" "--module_name=bcrypt_lib" "--module_path=D:\\Project\\test\\bb\\back\\node_modules\\bcrypt\\lib\\binding" "--napi_version=4" "--node_abi_napi=napi" "--napi_build_version=0" "--node_napi_label=node-v72"

gyp ERR! cwd D:\Project\test\bb\back\node_modules\bcrypt

npm ERR! code ELIFECYCLE

npm ERR! errno 1

npm ERR! bcrypt@3.0.6 install: `node-pre-gyp install --fallback-to-build`

npm ERR! Exit status 1

npm ERR!

npm ERR! Failed at the bcrypt@3.0.6 install script.

npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:

npm ERR!     C:\Users\User\AppData\Roaming\npm-cache\_logs\2019-10-18T08_33_22_379Z-debug.log

bcrypt를 인스톨하면 이런 오류가 뜹니다.

3
hsjo12 프로필

질문이요 hsjo12 1일 전

1.

강의에서, 

코멘트가 DB에 제대로 들어갔음에도 불구하고, 

ADD_COMMENT_FAILURE 로 떴잖아요.

그런데 case LOAD_COMMENTS_SUCCESS를 리듀서 에서 정의해주자, ADD_COMMENT_SUCCESS 가 됬다고 되는데, 도대체 이 둘이 무슨 상관이 있는건가요... ? 

2. 강의에서 늘 불변성이 라고 언급하시잖아요.

이 불변성이 이전의 값들은 건들이지 않고 새롭게 추가된것들 추가하는게 불변성이 맞는건가요?

1
huhjaewoo 프로필

에러관련 질문 입니다. huhjaewoo 1일 전

SequelizeConnectionError: Client does not support authentication protocol requested byserver; consider upgrading MySQL client

이런 에러는 왜 나는건가요?

3
terecal 프로필

프로젝트를 다시 생성한뒤 디비 설정을 할때 디비 설정이 바뀌나여? terecal 1일 전

warning이 출력되는데 뭔가 잘못된 것일까여?

1
hsjo12 프로필

질문이요. hsjo12 1일 전

지금 이 saga 부분에서 서버로 넘길떼요. 

 return axios.get(userId ? `user/${userId}`'/user/',

userId 를 안 넘겨줬을때, 자기 자신의 정보를 들오 오잖아요.

라우터는, 

router.get('/', (reqres=> { // /api/user/
    if(!req.user){
        return res.status(401).send('로그인 필요합니다.')
    }
    const user = Object.assign({},req.user.toJSON());
    delete user.password;
    return res.json(user); 


 } );

이렇게 생겼고요. 

그런데 문제는, 

userProfile.js 이부분 return 부분에서,,,

  actions={
              [
              <div key="twit">짹짹<br /> {me.Post?me.Post.length:0}</div>,
              <div key="following">팔로잉<br />{me.Followings? me.Followings.length:0}</div>,
              <div key="follower">팔로워<br />{me.Followers? me.Followers.length:0}</div>,
            
              ]
            }

me.Post, Following, Follower 자체가 라우터에서 보내주는 user값에 속하지 않는거 같은데요..

저기 라우터 부분에 따로 넣어 줘야하나요...?

깃에서는 라우터는 저렇게 되어있던데.. 무엇이 어덯게 된걸까요..

1
unknown o 프로필

이런 부분이 이해가 안됩니다. unknown o 1일 전

setCommentFormOpened(prev => !prev);

여기서 prev => !prev가 어떤식으로 작동이 되는지 잘 모르겠는데...

제가 기초가 부족한걸까요??

2
lolola 프로필

User 의 프로퍼티가 대문자 소문자 바뀌어서나오는현상 lolola 2일 전

Retweet할때 

RETWEET_REQUEST요청으로 리트윗을 했을시에

리트윗이 게시글이 mainposts에 더해지게되는데요

이때 post의 Retweet의

User객체가 {id:1,userName:"제로초"} 이던녀석이 새로고침만하면

{id:1, UserName:"제로초"} 

userName프로퍼티가 UserName으로 바뀌어버립니다(앞글자가 대문자).

그래서 화면렌더링할떄 userName으로해놔서 안나오게되는데 

왜 리트윗하고난뒤엔 멀쩡한게 새로고침해서 LOAD_MAIN_POSTS_REQUEST를통해서 가져올땐 UserName으로 가져오는지 잘모르겠습니다

3
unknown o 프로필

질문있습니다. unknown o 2일 전

const [term, setTerm] = useState(false);



const onSubmit = useCallback((e) => {

    e.preventDefault();

    if (password !== passwordCheck) {

      return setPasswordError(true);

    }

    if (!term) {

      return setTermError(true);

    }

  }, [password, passwordCheck, term]);



{termError && <div style={{ color: 'red' }}>약관에 동의하셔야 합니다.</div>}

강의에 있는 코드에서 필요한 부분만 뽑아 봤습니다.

먼저 맨마지막 코드는 termError가 true일 때 화면에 표시되는 코드잖아요.

그래서 체크박스에 체크를 안하면 경고문이 뜨게하는거고요.

term은 초기값이 false이고요.

onSubmit에서 !term이면 !term의 값은 true인거고..

그러면 term이 true일 때 setTermError가 true가 된다는 뜻인거고...

경고문은 term이 false일 때(체크박스에 체크를 안 한 상태) 나와야되는데 !term은 true인거잖아요.

그런데 체크박스를 체크 안 한 상태(false)에서 제출을 하면 정상적으로 경고문이 뜨는데 이해가 안가서 질문드립니다.

3
Jiyeol Lee 프로필

formData(req.body에 담기는)를 백단에서 아예 받지 못하는(or 인식하지 못하는) 문제 Jiyeol Lee 2일 전

SequelizeValidationError: notNull Violation: Post.title cannot be null 

제로초님 강의듣고 노드버드참고하면서 개인 플젝 하고 있는데요. 

새로운 포스트(게시물)을 작성하기 위해 form에 있는 정보를 백단으로 전송하면 위와 같은 에러가 납니다.

DB에 포스트 생성할때 title을 제일 먼저 넣어주기때문에 애초에 req.body.title에 값이 없는 것으로 보입니다. req.body에 담긴 값이 없는 것인지 아니면 담겼는데 백단으로 전송되면서 파싱, 인코딩 이런쪽에 문제가 있는 것인지 도무지 모르겠네요..

form태그는 따로 enctype 지정해주지는 않았고요. 저는 파일 업로드하는 부분이 없기 때문입니다. 혹시 몰라서 강의와 동일하게 enctype설정해도 딱히 문제에 변화는 없었습니다. 

새로운 포스트 생성에 관한 saga코드도 노드버드와 동일하고, 백단 index.js 파일에서 미들웨어 실행 순서도 동일합니다.

그리고 아래와 같이 네트워크 탭보면 formData는 잘 담겨서 전송은 됩니다.

어떤 식으로 접근해서 해결해야할지 접근법이라도 알려주시면 감사하겠습니다.

1
이상욱 프로필

_app.js의 Component 이 왜 elementType 타입인가요? 이상욱 3일 전

npmjs를 보면

  // A React element (ie. <MyComponent />).
  optionalElement: PropTypes.element,
 
  // A React element type (ie. MyComponent).
  optionalElementType: PropTypes.elementType,

라고 써져 있는데, 

_app.js에 <Component />로 jsx타입으로 사용되었으면 타입이element가 되어야 하는 거 아닌가요? 

element 타입은 어떨 때 사용되는 건지 궁금합니다.

1
hsjo12 프로필

질문이여 hsjo12 3일 전

해쉬태그 검색할 때요 

router.get('/:tag'async(req,res,next)=>{
    try{
        const posts = await db.Post.findAll({
            include : [{
                model : db.Hashtag,
                where : { namedecodeURIComponent(req.params.name)}, 
           },{ 
                model:db.User,
                attributes:['id','nickname']
            }]
        });
   res.json(posts)
    }catch(e){
        console.error(e)
        next(e)
    }
});

모든 포스트를 불러 들이고 그 다음에 , 해쉬태그는 검색된것만 부르고, 유저는 모든 유저를 불러들이는건가요?

1.

모든 포스트 + 검색된 해쉬태그 + 모든 유저 ?

아니면 

검색된 해쉬태그가 where 같이 조건이 되어서, 

2.

검색된 해쉬태그만 들어있는 포스트들 + 검색된 해쉬태그  + 검색된 해쉬태그를 갖고잇는 포스트들을 쓴 유저들만 

1번인가요? 2번인가요 ?

1
unknown o 프로필

action.data.postId unknown o 3일 전

const postIndex = state.mainPosts.findIndex(v => v.id === action.data.postId);

여기서 action.data.postId는 어디에서 오는 값인가요??

1
unknown o 프로필

질문있습니다 unknown o 3일 전

  const onToggleComment = useCallback(() => {
    setCommentFormOpened(perv => !prev);
 }, []);

댓글 아이콘 클릭했을 때 폼이 켜지고 꺼지고 하는 기능은 위의 코드만 쓰면 되는건가요??

1