• 카테고리

    질문 & 답변
  • 세부 분야

    풀스택

  • 해결 여부

    미해결

그룹의 게시글의 댓글 질문합니다 ///////

20.05.06 23:54 작성 조회수 184

0

https://www.inflearn.com/questions/33679

전에 답변주신 덕분에 ㅠㅠ ♡..  LOAD_MAIN_POSTS_REQUEST 게시물로드하기 성공했어요~!

그룹에 속한 게시물로 구조를 바꾸어준 후,

댓글 불러오기 LOAD_COMMENTS_REQUEST에 네트워크탭에 Request URL 에 전과 같은 undefined 오류가 나는 것을 확인했습니다

코드수정 후, 네트워크탭에서 성공의 200표시가 떳습니다.!

그런데 리덕스 데브툴즈에는  LOAD_COMMENTS_FAILURE가 뜨고 화면에서도 댓글이 보이지않았어요...

타입에러인 것을 확인했습니다,

강의하신 mainPosts의 data구조를 (어느그룹에 속한 게시물인지 데이터를보내기위해)

data에 gpostId와 content로 나누어놨었어요

그래서인지 findIndex함수가 작동하지 않는것을 확인하고,

리듀서에서 mainPosts의 배열을 뽑아내기위해 ---->  mainPosts.content로 수정했습니다.

<  post.js / reducers/ front >

// 댓글 불러오기
        case LOAD_COMMENTS_SUCCESS: {
           // console.log("state.mainPosts.content",state.mainPosts.content);
            const postIndex = state.mainPosts.content.findIndex(v => v.id === action.data.postId);
           // console.log("postIndex",postIndex);
            const post = state.mainPosts[postIndex];
           // console.log("post",post);
            const Comments = action.data.comments;
           // console.log("Comments",Comments);
            const mainPosts = [...state.mainPosts.content];
           // console.log("mainPosts",mainPosts);
            mainPosts[postIndex] = { ...postComments };
           // console.log("new : ",mainPosts[postIndex]);
            return {
              ...state,
              mainPosts,
            };
       }

reducer / console.log

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

이렇게 수정해주니 리덕스 데브툴즈에서도 LOAD_COMMENTS_SUCCESS

가 떳고 네트워크탭에서도 GET 방식으로 댓글이 잘 받아와지는 것을 확인할수있었어요.! 

그런데 화면에서는 다른화면으로 넘어가서 원하는 결과가 나오지 않아요...ㅠㅠ

오류또한 발견핧수없었습니다.

^ 결론 : 

댓글버튼을 클릭하면 dispatch로 LOAD_COMMENTS_REQUEST가 실행되고

컴포넌트<ContentForm> 에서 { post } 프롭값에 db.Comment 테이블에서 Comments 배열이 불러와졌었는데,,

 post를 콘솔로 확인해보면 Comments 배열이 불러와지지 않아요,,,,

post.Comments로 결과를 화면에 나타나게 했는데 값이 불려와지지 않는게,,

왜그런지 알고싶습니다.ㅠㅠ

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

<  post.js / sagas / front >

// 댓글 불러오기
function loadCommentsAPI(postId) {
    return axios.get(`/post/${postId}/comments`);
}  
function* loadComments(action) {
    try {
        const result = yield call(loadCommentsAPIaction.data);
        yield put({
          type: LOAD_COMMENTS_SUCCESS,
          data: {
            postId: action.data,
            comments: result.data,
          },
        });
    } catch (e) {
        console.error(e);
        yield put({
          type: LOAD_COMMENTS_FAILURE,
          error: e,
        });
    }
}
function* watchLoadComments() {
    yield takeLatest(LOAD_COMMENTS_REQUESTloadComments);
}

< ContentForm.js / Component / front > 

const ContentForm = ({post}) => {
    const [commentFormOpenedsetCommentFormOpened] = useState(false);
    const [commentTextsetCommentText ] = useState('');
    const { me } = useSelector(state => state.user);
    const { commentAddedisAddingCommentmainPosts } = useSelector(state => state.post);
    const dispatch = useDispatch();    
    const liked = me && post.Likers && post.Likers.find(v => v.id === me.id);
    //댓글창토글
    const onToggleComment = useCallback(() => {
        setCommentFormOpened(prev => !prev);
        if (!commentFormOpened) {
          // 댓글창 켤때 불러오기
            dispatch({
              type: LOAD_COMMENTS_REQUEST,
              data: post.id,
            });
          }
     }, []);
    // 댓글
    const onChangeComment = useCallback((e=> {
        setCommentText(e.target.value);
   }, []);
    // 댓글올리기 사이클
    const onSubmitComment = useCallback((e=> {
        e.preventDefault();
        if(!me){
            return alert('로그인이 필요합니다.');
        }
        return dispatch({
            type: ADD_COMMENT_REQUEST,
            data:{
                postId: post.id,
                content: commentText,
            },
        });
    }, [me && me.idcommentText]);    
    // 댓글 성공시, 빈텍스트로 
    useEffect(() => {
        setCommentText('');
    },[commentAdded === true]);
    // 댓글삭제하기
    const onRemoveComments = useCallback(userId => () => {
        alert('댓글을 삭제하시겠습니까?');
        if(me.id === post.User.id)
        dispatch({
          type: REMOVE_COMMENT_REQUEST,
          data: userId,
        });
   });
    // 댓글 변수선언
    var listIndex;
    // 게시글 삭제
    const onRemovePost = useCallback(userId => () => {
        if(me.id === post.User.id)
        alert('게시물을 삭제하시겠습니까?');
        dispatch({
          type: REMOVE_POST_REQUEST,
          data: userId,
        });
        if(me.id !== post.User.id)
        alert('다른 사용자의 게시물은 삭제할 수 없습니다.');
    });  
    // 좋아요 토글
    const onToggleLike = useCallback(() => {
        if (!me) {
          return alert('로그인이 필요합니다!');
        }
        if (liked) { // 좋아요 누른 상태
          dispatch({
            type: UNLIKE_POST_REQUEST,
            data: post.id,
          });
        } else { // 좋아요 안 누른 상태
          dispatch({
            type: LIKE_POST_REQUEST,
            data: post.id,
          });
        }
    }, [me && me.idpost && post.idliked]);
  
    return(
        <>
            <div className="postbox">   
                <div className="contBox">
                <p>{post.User.nickname} 님의 게시물 - 좋아요 : {post.Likers.length }  </p>
                    <PostImages images={post.Images} />
                    <div>{post.content}</div>
                </div>
                <div className="btnsbox">
                    <button type="button" className="commentBtn"  value={commentFormOpened} onClick={onToggleComment} />
                    { liked ? <button type="button" className="likeBtnred" onClick={onToggleLike} /> :
                    <button type="button" className="likeBtnline" onClick={onToggleLike} /> } 
                    <button type="button" className="removeBtn" onClick={onRemovePost(post.id)} />
                    {commentFormOpened===true &&
                        <form className="commentbox" onSubmit={onSubmitComment}>
                            <textarea className="comment" value={commentText} onChange={onChangeComment} />
                            <button type="primary" htmltype="submit" className="combtn" loading={isAddingComment} >COMMENT</button>
                        </form>
                    }
                    {/* 댓글올라갈부분 */}
                    {commentFormOpened===true && (
                        <div style={{display:"inline-block"width:"100%"}}>
                            <p style={{marginLeft:"10px"}}>{commentAdded ? '댓글' + post.Comments.length : '댓글''0'}</p>
                            <div className="comline"></div>
                            {console.log("mainPosts.content???: ",mainPosts.content,"post???: ",post)}
                            {(()=>{
                                if(post.Comments){
                                    listIndex = post.Comments.map((el)=>
                                        (
                                        <li style={{listStyle:"none"display:"inline-block"clear:"both"}} >
                                            {console.log("el",el)}
                                            {el.User.nickname} : {el.content} 
                                            { el.UserId === me.id ? 
                                            <button type="button" className="remove" onClick={onRemoveComments(post.id)} > REMOVE </button>
                                            : "" }
                                        </li>
                                        )
                                   )
                                }
                                return(
                                    <ul> 
                                        {listIndex} 
                                    </ul>
                                );
                            })()}
                            
                        </div>
                        )
                    }
                </div> 
            </div>
        </>
    );
};
ContentForm.propTypes={
    post: PropTypes.shape({
        User: PropTypes.object,
        content: PropTypes.string,
        createdAt: PropTypes.string,
    }),
};
export default ContentForm;

< post.js / routes / back >

// 댓글불러오기
router.get('/:id/comments'async (reqresnext=> {
  try {
    const post = await db.Post.findOne({ where: { id: req.params.id } });
    if (!post) {
      return res.status(404).send('포스트가 존재하지 않습니다........');
    }
    const comments = await db.Comment.findAll({
      where: {
        PostId: req.params.id,
      },
      order: [['createdAt''ASC']],
      include: [{
        model: db.User,
        attributes: ['id''nickname'],
      }],
    });
    res.json(comments);
  } catch (e) {
    console.error(e);
    next(e);
  }
});

답변 5

·

답변을 작성해보세요.

0

아, 용량때문에 따로 불러오는 경우에는  액션을 하나 더 만들고, 리듀서에서도 객체 속성 하나 만들어서 거기에 불러오시고 그 때는 게시글 객체 안에 Comments가 안 들어있으니 리듀서에서 방금 만든 속성 가져오셔야 합니다.

{ model: Comment,
  include: [{ model: User }],
}

이렇게 include한 모델 안에서 한 번 더 include하시면 됩니다.

0

지니님의 프로필

지니

질문자

2020.05.08

댓글버튼을 누르면 dispatch LOAD_COMMENTS_REQUEST로 불러오고싶은건데,,

애초에 게시물불러오기할때 댓글도같이불러오게 하면 용량문제때문에 그렇게 하시지 않았나요??..

그럼 질문을 바꿔서,,

게시물 불러올때 include 로 Comment 해주고 콘솔로 확인해보니 제대로 불러와지긴하는데 

Comment 안에 User 의 정보를 같이 담아서 불러오고싶은데 그건 어떻게 하나요?

UserId 만나오고  User. nickname을 구하고싶습니다.

  1. CommentsArray(3)
    1. 0:
      1. PostId1
      2. UserId2
      3. content"귀여워요~"
      4. createdAt"2020-04-22T10:58:46.000Z"
      5. id2
      6. updatedAt"2020-04-22T10:58:46.000Z"
// 게시물'들' 불러오기
router.get('/:id'async (reqresnext=> { // GET /api/posts/100/개발자
  try {
    const gpost = await db.Gpost.findOne({ where: { id: req.params.id } }); 
    if (!gpost) {
      return res.status(404).send('포스트가 존재하지 않습니다.!!!!');
    }
    const posts = await db.Post.findAll({ // api/posts/1/comments
      where: {
        GpostId: req.params.id,
      },
      include: [{
        model: db.User,
        attributes: ['id''nickname'],
      },{
        model: db.Image,
      },{
        model: db.Comment,
      },{
        model: db.User,
        through: 'Like',
        as:'Likers',
        attributes:['id'],
      }],
      order: [['createdAt''DESC']], // DESC는 내림차순, ASC는 오름차순
    });
    res.json(posts);
  } catch (e) {
    console.error(e);
    next(e);
  }
});
// 댓글불러오기
router.get('/:id/comments'async (reqresnext=> { // api/post/1/comments
  try {
    const post = await db.Post.findOne({ where: { id: req.params.id } });
    if (!post) {
      return res.status(404).send('포스트가 존재하지 않습니다........');
    }
    const comments = await db.Comment.findAll({
      where: {
        PostId: req.params.id,
      },
      order: [['createdAt''ASC']],
      include: [{
        model: db.User,
        attributes: ['id''nickname'],
      }],
    });
    res.json(comments);
  } catch (e) {
    console.error(e);
    next(e);
  }
});

0

게시글 불러올 때 include Comment도 하셔야 속성에 Comments 추가됩니다.

0

지니님의 프로필

지니

질문자

2020.05.08

< post.js / routes / back > 댓글 불러오는 router에 include Comment 해주어야하나요??

0

include Comment가 제대로 되어있나요??