• 카테고리

    질문 & 답변
  • 세부 분야

    풀스택

  • 해결 여부

    해결됨

포스트 트윗 시 게시글이 추가되지 않고, 요청 무한로딩에 걸립니다. TypeError: Cannot read properties of undefined (reading 'data')

23.10.27 09:15 작성 23.10.27 09:37 수정 조회수 395

0

안녕하세요 제로초님
현재 섹션3 redux-saga 연동하기 - 게시글, 댓글 saga 작성하기 영상의
Warning: Encountered two children with the same key, 2. 에러 해결까지 수강한 학생입니다!

로그인 후 포스트 폼에 글을 입력 후 트윗하기 버튼을 누르는 순간 콘솔 창에 에러가 발생했습니다.게시글석세스0.PNGredux-devtools로 포스트 추가 액션의 변화를 살펴보니
ADD_POST_SUCCESS 포스트 추가 성공 액션이 실행되고 있지 않았습니다! 게시글석세스안됨.PNG게시글석세스안됨2.PNG콘솔에 있는 에러 메시지 번역은 다음과 같았습니다.
게시글석세스에러번역.PNG
번역을 읽고 data가 undefined이며, addPost에 이상이 있음을 확인했고,
컴포넌트 폴더의 PostForm.js와 reducers/post.js, sagas/post.js를 코드를 확인했습니다.

https://github.com/ZeroCho/react-nodebird/blob/master/ch4/front/components/PostForm.js
제로초님의 깃허브 챕터4와 구글 검색을 참고 후 가장 의심되는 코드 부분을 올립니다!

※ 관련 없는 코드는 . . . 으로 요약 표시하였습니다.

 

components/PostForm.js

가독성을 위해 setText는 setPostText로, text는 postText로 바꾸어 코딩했습니다.

// reducer 포스트 추가 요청 액션 불러오기
import { addPost } from '../reducers/post';



// 포스트 폼 컴포넌트(사용자 정의 태그)
const PostForm = () => {
  const dispatch = useDispatch();
  const [postText, onChangePostText, setPostText] = useInput('');
  const { imagePaths, addPostLoading, addPostDone } = useSelector((state) => state.post);


  /* ----- 포스트 추가 완료 시 포스트 폼 글자 지우기 ----- */
  useEffect(() => {
    if (addPostDone) {
      setPostText('');
    }
  }, [addPostDone]);


  /* ----- 포스트 폼 제출 시 포스트 카드 추가 ----- */
  const onSubmitForm = useCallback(() => {
    dispatch(addPost(postText));
  }, [postText]);

  // const onSubmitForm = useCallback(() => {
  //   dispatch({
  //     type: ADD_POST_REQUEST,
  //     data: addPost,
  //   });
  // }, [postText]);

  return (
    <Form . . . />

      <Input.TextArea
        id="post-form"
        value={postText}
        onChange={onChangePostText}
        maxLength={140}
        placeholder="어떤 신기한 일이 있었나요?"
      />

. . .

        {/* ---------- 포스트 작성 버튼 ---------- */}
        <Button
          type="primary"
          style={{ float: 'right' }}
          htmlType="submit"
          loading={addPostLoading}
        >
          트윗하기
        </Button>
      </div>
    </Form>
  );
};

 

reducers/post.js

// ShortId 라이브러리 불러오기
import shortId from 'shortid';



// 중앙 데이터 저장소(기본 state)
export const initialState = {
  /* ---------- 메인 포스트 더미 데이터 ---------- */
  mainPosts: [{
    . . .
  }],
  /* ---------- 이미지 업로드 시 경로 저장 ---------- */
  imagePaths: [],
  /* ---------- 포스트 추가 시도 중, 완료, 에러 ---------- */
  addPostLoading: false,
  addPostDone: false,
  addPostError: null,
}

// 포스트 추가 액션 : 요청, 성공, 실패
export const ADD_POST_REQUEST = 'ADD_POST_REQUEST';
export const ADD_POST_SUCCESS = 'ADD_POST_SUCCESS';
export const ADD_POST_FAILURE = 'ADD_POST_FAILURE';

// 포스트 추가 요청 액션 생성함수(action creator)
export const addPost = (data) => ({
  type: ADD_POST_REQUEST,
  data,
});

// 포스트 더미 데이터
const dummyPost = (data) => ({
  id: shortId.generate(),
  content: data,
  User: {
    id: 1,
    nickname: '다랑',
  },
  Images: [],
  Comments: [],
});

// 리듀서(reducer) : (이전 상태, 액션) => 다음 상태
const reducer = (state = initialState, action) => {
  switch (action.type) {
    /* ----- 포스트 추가 요청 리듀서 ----- */
    case ADD_POST_REQUEST:
      return {
        addPostLoading: true,
        addPostDone: false,
        addPostError: null,
      };
    /* ----- 포스트 추가 성공 리듀서 ----- */
    case ADD_POST_SUCCESS:
      return {
        ...state,
        mainPosts: [dummyPost(action.data), ...state.mainPosts],
        addPostLoading: false,
        addPostDone: true,
        // 사용자 더미 데이터
        me: dummyUser(action.data),
      };
    /* ----- 포스트 추가 실패 리듀서 ----- */
    case ADD_POST_FAILURE:
      return {
        addPostLoading: false,
        addPostError: action.error,
      };
    default:
      return state;
  }
};

 

sagas/post.js

// Saga 이펙트 불러오기
import { all, fork, call, takeLatest, put, delay } from 'redux-saga/effects';

// Axios 라이브러리 불러오기
import axios from 'axios';

// reducer 포스트 추가, 답글 추가 액션 불러오기
import {
  ADD_POST_REQUEST, ADD_POST_SUCCESS, ADD_POST_FAILURE,
} from '../reducers/post';



// addPost 실행 시 서버에 addPostAPI 요청
function addPostAPI(data) {
  return axios.post('/api/post', data)
}
// ADD_POST_REQUEST 액션이 실행되면 addPost 함수 실행
function* addPost(action) {
  try {
    // const result = yield call(addPostAPI, action.data);
    /* ----- 요청 성공 시 ADD_POST_SUCCESS 액션 디스패치 ----- */
    yield delay(1000);
    yield put({
      type: ADD_POST_SUCCESS,
      data: action.data,         // 성공 결과
    });
  } catch (err) {
    /* ----- 요청 실패 시 ADD_POST_FAILURE 액션 디스패치 ----- */
    yield put({
      type: ADD_POST_FAILURE,
      error: err.response.data,  // 실패 결과
    });
  }
}

 

강의 잘 보고 있습니다!
항상 정성스러운 답변 남겨주셔서 감사합니다 제로초님!

답변 2

·

답변을 작성해보세요.

0

이가은님의 프로필

이가은

질문자

2023.10.29

포스트 추가 요청 리듀서와 포스트 추가 성공 리듀서에 ...state를 넣어,
게시글이 정상적으로 추가되도록 코드를 수정하였습니다! 감사합니다 제로초님!

0

saga의 addPost에서 data 앞에 것이 undefined라는 뜻입니다. 에러 메시지에 에러 위치 나와있습니다.

https://github.com/ZeroCho/react-nodebird/blob/master/ch4/front/sagas/post.js#L56-L67

여기서 action이나 err.repsonse 둘 중 하나가 없는 것 같은데요. catch문 안에서는 무조건 console.error(err) 같이 넣으세요.