게시글
질문&답변
그룹의 게시글의 댓글 질문합니다 ///////
댓글버튼을 누르면 dispatch LOAD_COMMENTS_REQUEST로 불러오고싶은건데,, 애초에 게시물불러오기할때 댓글도같이불러오게 하면 용량문제때문에 그렇게 하시지 않았나요??.. 그럼 질문을 바꿔서,, 게시물 불러올때 include 로 Comment 해주고 콘솔로 확인해보니 제대로 불러와지긴하는데 Comment 안에 User 의 정보를 같이 담아서 불러오고싶은데 그건 어떻게 하나요? UserId 만나오고 User. nickname을 구하고싶습니다. Comments: Array(3) 0: PostId: 1 UserId: 2 content: "귀여워요~" createdAt: "2020-04-22T10:58:46.000Z" id: 2 updatedAt: "2020-04-22T10:58:46.000Z" // 게시물'들' 불러오기 router.get('/:id', async (req, res, next) => { // 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 (req, res, next) => { // 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
- 5
- 306
질문&답변
그룹의 게시글의 댓글 질문합니다 ///////
댓글 불러오는 router에 include Comment 해주어야하나요??
- 0
- 5
- 306
질문&답변
saga axios.get 주소질문...............
감사합니다!!!ㅠㅠ
- 0
- 11
- 572
질문&답변
saga axios.get 주소질문...............
!!! ㅜㅠㅠㅠ 잘뜹니다 감사합니다ㅜ cttf !== undefined && cttf.map((i)=>{ 이렇게 해줘도 뜨는데 cttf && cttf.map 이랑 뜻이 다른가요??
- 0
- 11
- 572
질문&답변
saga axios.get 주소질문...............
cttf 에 관련해선 딱히 오류뜨는게 없어요ㅜ (사진) 아래처럼 코드 수정후에 다시 실행시켜봤더니 화면에 잘 나왔다가 TypeError: Cannot read property 'map' of undefined오류가 번갈아가면서 뜨네요 var cttf = mainPosts.content; { cttf.map((i)=>{ return( ContentForm key={i} post={i} /> ); })}
- 0
- 11
- 572
질문&답변
saga axios.get 주소질문...............
map 과 관련된 구글사이트 읽어봐도 문제점을 찾지못해질문남깁니다..
- 0
- 11
- 572
질문&답변
saga axios.get 주소질문...............
감사합니다!! useEffect 로 dispatch 하는 부분에 data에 gpost의 id 값넣어주니 LOAD_MAIN_POSTS_SUCCESS 가 뜨네요! 그런데 mainPosts.map 으로 게시물을 화면에 렌더링 했었는데 TypeError: mainPosts.map is not a function 라고 오류가 뜹니다. 콘솔로 mainPosts 찍어보니 saga에서 보내주는 구조로 data값이 전달되는것을 확인했습니다. (사진) 그래서 cttf 라는 변수에 content만 담아서 map으로 리턴 시켜주려 했는데 여전히 타입에러 오류메세지가 떠요.. cttf = mainPosts.content; 구조가 getinitialprops로 연동된 페이지(posted페이지) 안에있는 컴포넌트:의 자식컴포넌트:을 map으로 리턴해주려 하고 있습니다. 컴포넌트 에서는 인자로 { gpost }로 그룹의 데이터를 받아오고 컴포넌트 에서는 인자로 { post } 로 게시물의 데이터를 받게 Proptype 설정을 해주었어요 ***** 뭐때문에 생기는 오류인지 알고싶습니다.!! (사진) 컴포넌트 코드 입니다. const UploadForm = ({gpost}) => { const dispatch = useDispatch(); const [text, setText ] = useState(''); const { isAddingPost, postAdded, mainPosts, imagePaths } = useSelector(state => state.post); const imageInput = useRef(); // 게시물 로드하기 // useEffect(() => { // dispatch({ // type: LOAD_MAIN_POSTS_REQUEST, // data: gpost.id, // }); // }, []); useEffect(() => { setText(''); },[postAdded === true]); const onSubmitForm = useCallback((e) => { e.preventDefault(); if (!text || !text.trim()) { return alert('게시글을 작성하세요.'); } const formData = new FormData(); imagePaths.forEach((i) => { formData.append('image', i); }); formData.append('content', text); formData.append('GpostId', gpost.id); dispatch({ type: ADD_POST_REQUEST, data: formData, }); }, [text, imagePaths, gpost.id]); // 이미지업로드 const onChangeImages = useCallback((e) => { console.log(e.target.files); const imageFormData = new FormData(); [].forEach.call(e.target.files, (f) => { imageFormData.append('image', f); }); dispatch({ type: UPLOAD_IMAGES_REQUEST, data: imageFormData, }); }, []); var cttf; return ( div> 부분 {/* 게시물올라가는부분 */} div className="letsbegin"> div> {(()=>{ console.log("mainPosts : ",mainPosts); cttf = mainPosts.content; cttf.map((i)=>{ ContentForm key={i} post={i} /> }); })()} {/* {mainPosts.map((i)=>{ return( ); })} */} div> div> div> ); }; UploadForm.propTypes={ gpost: PropTypes.shape({ User: PropTypes.object, title: PropTypes.string, }), }; export default UploadForm; const ContentForm = ({post}) => { const [commentFormOpened, setCommentFormOpened] = useState(false); const [commentText, setCommentText ] = useState(''); const { me } = useSelector(state => state.user); const { commentAdded, isAddingComment } = 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.id, commentText]); // 댓글 성공시, 빈텍스트로 useEffect(() => { setCommentText(''); },[commentAdded === true]); // 댓글삭제하기 const onRemoveComments = useCallback(userId => () => { alert('댓글을 삭제하시겠습니까?'); // console.log("포스트아이디",me.id, post.User.id) if(me.id === post.User.id) dispatch({ type: REMOVE_COMMENT_REQUEST, data: userId, }); }); // 댓글 변수선언 var listIndex; // 게시글 삭제 const onRemovePost = useCallback(userId => () => { // console.log("포스트아이디",me.id, post.User.id) 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.id, post && post.id, liked]); 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} >COMMENTbutton> form> } {/* 댓글올라갈부분 */} {commentFormOpened===true && ( div style={{display:"inline-block", width:"100%"}}> p style={{marginLeft:"10px"}}>{commentAdded ? '댓글' + post.Comments.length : '댓글'+ '0'}p> div className="comline">div> {(()=>{ if(post.Comments){ // console.log(post.Comments[0]) listIndex = post.Comments.map((el)=> ( li style={{listStyle:"none", display:"inline-block", clear:"both"}} > {el.User.nickname} : {el.content} { el.User.id === 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;
- 0
- 11
- 572
질문&답변
saga axios.get 주소질문...............
saga // routes // reducer 중 어느부분말씀하시는건가요?..?
- 0
- 11
- 572
질문&답변
테이블간의 부모 자식관계
1번 질문은 강의속 코드가 거의 같은 상태에서 그룹에 속해있는 게시물로 수정 해주게 되면, 게시물의 불변성을 해줘야 하는지 궁금해서 질문드렸었던거구요~! 백엔드서버코드를 저렇게 수정해주니 게시물이 업로드와 불러오기 둘다 안되서 추가해줘야할 사항이 있는지 궁금합니다ㅜㅜ 에러코드는 네트워크탭과 콘솔에서 뜨지 않아요.. 리덕스 데브툴즈에서 Failure 뜨고 데브툴즈 속 Action의 data 부분에는 빈객체 { } 가 뜨면서 아무것도 담겨있지 않습니다. // 게시물'들' 불러오기 router.get('/:id/:title', async (req, res, next) => { // GET /api/posts try { // const gpost = await db.Gpost.findOne({ // where: { id: req.params.id }, // include: [{ // model: db.Post, // as: 'Posts', // attributes: ['id'], // where: { title : decodeURIComponent(req.params.title) }, // }], // }); // 그룹이있는지 // if (!gpost) { // return res.status(404).send('포스트가 존재하지 않습니다.'); // } const posts = await db.Post.findAll({ // where: { // GpostId: req.params.id, // }, // order: [['createdAt', 'ASC']], include: [{ model: db.User, attributes: ['id', 'nickname'], },{ model: db.Image, },{ model: db.User, through: 'Like', as:'Likers', attributes:['id'], }], order: [['createdAt', 'DESC']], // DESC는 내림차순, ASC는 오름차순 }); res.json(posts); } catch (e) { console.error(e); next(e); } }); "(그룹의 id를 통해) 해당그룹에 속한 게시물들만 찾아서 불러와라" 라고 하고싶어서 저부분을 추가해준것인데,,, 다시 주석을 해주면 불러와지긴합니다만, 모든그룹에서 같은 게시물들이 모두 불러와 집니다. 추가해줘야할 사항, 수정해줘야할 부분이 있는지 알려주세요 제로초님.....! 백엔드 부분 ch5, ch6 반복적으로 복습해줘도 생각해준대로 코드짜려니 잘안되네요ㅠ 유투브 리액트 게임 무료강좌도 다보고 왔는데도 아직 어려운 부분이 많아요~~..
- 0
- 3
- 155
질문&답변
댓글질문있습니다
버튼 만들어서 해주었어요 button type="button" className="remove" onClick={onRemoveComments(post.id)} > REMOVE button>
- 0
- 2
- 181