항해99/매일 기록

항해 99 - 2022.02.17.THU (댓글 기능)

<zinny/> 2022. 2. 17. 15:21
728x90
이번 챕터 일정
  • 02/11 (금) 19:00 까지 : S.A. 제출 완료✅
  • 02/12 (토) 오전 : S.A. 서면 피드백 확인✅
    • 백엔드 스코프가 너무 좁다고 하심
    • 기능이 좀더 추가 되어야 할듯
  • 02/14 (월) 저녁 : 팀별 프로젝트 중간 멘토링✅
  • 02/17 (목) 저녁 : 팀별 프로젝트 회고 멘토링
  • 02/18 (금) 09:00 : 클론코딩 주차 발제

오늘 내가 할 일 

  • 댓글 기능 구현하기
    • 각 게시글에 맞는 댓글을 보여줘야함 (서버에서 값을줄 때 이미 처리해서 줘서 잘 사용만 하면 됨) ✅
    • 리로딩 될때 데이터가 날라가지 않아야 함(&&을 사용해서 해결 완료)✅
    • 댓글 작성할때 리로딩 안쓰고 바로 생성되게 
어제부터 리로딩 할때 데이터 날아가는 문제로 엄청 골머리였는데 구글링으로 오늘도 한껀한 나 자신 축하해,,

어쩜 문제는 계속 나오는지 댓글 작성시에 리덕스로 안 가고 바로 리로딩하게 해 놨는데
그렇게 하면 안 된다는 소리를 들어서,,,,
하,,,,
문제 해결 중인데 깃에서 충돌 날까 봐 아직 아무것도 못하는 중이다.... 흐규규

 

<댓글 코드>

/commnet.js

import {produce} from "immer";
import { createAction, handleActions} from "redux-actions";
import "moment"
import moment from "moment";
import instance from "../../shared/Request";

const GET_ONE_COMMENT ="GET_ONE_COMMENT";
const ADD_COMMENT ="ADD_COMMENT";
const LOADING = "LOADING"

const getOneComment = createAction(GET_ONE_COMMENT,(comment_list,post_id)=>({comment_list,post_id}))
const addComment = createAction(ADD_COMMENT, (post,post_id)=>({post,post_id}))

const initialState ={
    details:[],
}

const getOneCommentFB = (post_id)=>{
    return function(dispatch, getState, {history}){
        instance.get(`/api/comment/get/${post_id}`,{})
        .then(function(response){
            const comments = response.data.comment_list
            dispatch(getOneComment(comments,post_id))
        })
        .catch(function(error){
            console.log(error)
        })
    }
}

const addCommentFB =(user_comment,user_nick, post_id)=>{
    return function(dispatch, getState, {history}){
        const is_local = localStorage.getItem("is_login")
        const _comment ={
            user_nick: user_nick,
            user_comment :user_comment
        }
        let comment_list = {..._comment}
        instance.post(`/api/comment/save/${post_id}`,{
            user_nick: user_nick,
            user_comment :user_comment},
        instance.defaults.headers.common["Authorization"] = `Bearer ${is_local}`
        ).then((response)=>{
            dispatch(addComment(comment_list, post_id))
            window.location.reload()
            console.log(response)
        }).catch((error)=>{
            console.log(error)
        })
    }
}

export default handleActions({
    [ADD_COMMENT]:(state, action)=>produce(state, (draft)=>{
        console.log(action.payload)
        // draft.list[action.payload.post_id].push(action.payload.comment_list)
    }),
    [GET_ONE_COMMENT]:(state, action)=>produce(state,(draft)=>{
        console.log(action.payload)
        console.log(action.payload.comment_list)
        draft.details[action.payload.post_id] = action.payload.comment_list
    })
},
initialState
)

const actionCreators={
    addComment,
    addCommentFB,
    getOneComment,
    getOneCommentFB
}

export{actionCreators};

 

/commentList.js

import React from "react";
import { useDispatch } from "react-redux";
import {Grid, Input, Button} from "../elements/Index";
import { actionCreators as commentActions } from "../redux/modules/comment";

const CommentWrite=(props)=>{
  // console.log(props.post._id)
  let user_nick =  props.post.user_nick;
  let post_id = props.post._id
  const [user_comment, setComment] =React.useState("")
  const dispatch = useDispatch()

  return (
    <React.Fragment>
      <Grid is_flex>
        <Input
        value={user_comment}
        _onChange={(e)=>{setComment(e.target.value)}}
        placeholder="댓글을 입력해주세요:>"/>
        <Button width ="50px" margin="0px 2px" _onClick={()=>{dispatch(commentActions.addCommentFB(user_comment,user_nick, post_id)); setComment("")}}>작성</Button>
      </Grid>
    </React.Fragment>
  )
}

export default CommentWrite;

 

/commentWrite.js

import React from "react";
import { useDispatch, useSelector } from "react-redux";
import { Grid, Text } from "../elements/Index";
import { actionCreators as commentActions } from "../redux/modules/comment";
import moment from "moment";
import styled from "styled-components";

const CommentList =(props)=>{
  console.log(props)

  const post_id = props.post
  console.log(post_id)
  console.log(props.comment_list[post_id])
  const comments = props.comment_list[post_id]

  const dispatch = useDispatch()

    return (
      <React.Fragment>
          { comments&& comments.map((p,idx) => {
            if(p.articleId._id ===post_id){
              return (
              <React.Fragment key ={idx}>
                <CommentItem  {...p}/>
              </React.Fragment>)
            }
          })}
      </React.Fragment>
    )
  }
// }

export default CommentList;

const CommentItem =(props)=>{

  const createDate = moment(props.createDate).format('YYYY/MM/DD - HH:mm:ss')
  return(
    <Grid is_flex>
        <Text size="19px">{props.user_nick}</Text>
      <Grid is_flex margin="0px 10px 0px 30px">
        <Text size="19px" bold>{props.user_comment}</Text>
        <Text color="gray">{createDate}</Text>  
      </Grid>
    </Grid>
  )
}

CommentItem.defaultProps ={
  user_nick:"jini",
  user_comment:"이게 되네",
  createDate:"2022-02-04 10:00:00"
}

서버에서 가지고 온 데이터를 붙여주는 게 되면서도

새로고침을 하면 값이 날아가 버리다 못해 흰 화면이 나와버렸다. 

아무리 해봐도 답은 안 나오고.. 진짜 포기하고 싶어 졌는데 

오류중에 map을 실행할 수가 없다는 문구가 있어서 구글링을 해보니까 

문제 해결방법은 너무 간단했다. 

 

<TypeError: Cannot read property 'map' of undefined> 에러가 생긴 이유

리액트는 렌더링이 화면에 커밋된 후에 모든 효과를 실행한다

즉 데이터가 없어도 그냥 map이 냅다 실행돼버리기 때문이다... 어처구니,,

 

이럴 땐

&&를 이용해 보는 것이다. 

JavaScript에서 true && expression은 항상 expression으로 실행되고 false && expression은 항상 false로 실행된다. 따라서 조건이 참이면 && 바로 뒤의 요소가 출력에 나타난다. 거짓이면 React는 무시하고 건너뛴다. 

 

https://zinny-22.tistory.com/153

 

React 에러 - Cannot read properties of undefined

Cannot read properties of undefined "something" -> 값이 정의되지 않아서 읽을 수 없을 때 발생하는 오류!!!! 📌 원인 state가 비동기적이며 처음 렌더링 하기 전에 동작하기 때문에!!!!! state가 정의되지 않..

zinny-22.tistory.com

 

728x90