강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

문종현님의 프로필 이미지
문종현

작성한 질문수

[리뉴얼] React로 NodeBird SNS 만들기

바뀐 상태 적용하고 eslint 점검하기

로그인이 안돼서 질문 남겨요!

작성

·

698

0

제로초님  로그인이 안돼서 질문드립니다.

분명 전 강좌까지 잘 되던 로그인이 로딩표시만 나오고 로그인은 안돼서 무엇이 잘못된건지 햇갈려 질문남겨요 ㅜ

터미널에는

TypeError: Cannot read property 'forEach' of null

    at end (C:\Users\moonj\OneDrive\문서\test-project\practice\react-nodebird\REACT.SNS\front\node_modules\@redux-saga\core\dist\redux-saga-core.dev.cjs.js:1017:18)

    at Object.abort (C:\Users\moonj\OneDrive\문서\test-project\practice\react-nodebird\REACT.SNS\front\node_modules\@redux-saga\core\dist\redux-saga-core.dev.cjs.js:817:5)

    at C:\Users\moonj\OneDrive\문서\test-project\practice\react-nodebird\REACT.SNS\front\node_modules\@redux-saga\core\dist\redux-saga-core.dev.cjs.js:598:22

    at immediately (C:\Users\moonj\OneDrive\문서\test-project\practice\react-nodebird\REACT.SNS\front\node_modules\@redux-saga\core\dist\redux-saga-core.dev.cjs.js:60:12)

    at runForkEffect (C:\Users\moonj\OneDrive\문서\test-project\practice\react-nodebird\REACT.SNS\front\node_modules\@redux-saga\core\dist\redux-saga-core.dev.cjs.js:588:3)

    at runEffect (C:\Users\moonj\OneDrive\문서\test-project\practice\react-nodebird\REACT.SNS\front\node_modules\@redux-saga\core\dist\redux-saga-core.dev.cjs.js:1208:7)

    at digestEffect (C:\Users\moonj\OneDrive\문서\test-project\practice\react-nodebird\REACT.SNS\front\node_modules\@redux-saga\core\dist\redux-saga-core.dev.cjs.js:1275:5)

    at C:\Users\moonj\OneDrive\문서\test-project\practice\react-nodebird\REACT.SNS\front\node_modules\@redux-saga\core\dist\redux-saga-core.dev.cjs.js:677:5

    at Array.forEach (<anonymous>)

    at runAllEffect (C:\Users\moonj\OneDrive\문서\test-project\practice\react-nodebird\REACT.SNS\front\node_modules\@redux-saga\core\dist\redux-saga-core.dev.cjs.js:676:8)

The above error occurred in task watchAddPost

    created by postSaga

    created by watchAddComment

    created by postSaga

    created by rootSaga

Tasks cancelled due to error:

postSaga

postSaga

userSaga

이러한 에러가 뜨고

콘솔에서는 

이런 에러가 뜨는데 무엇이 해결책인지 모르겠어서 질문 남겨요

user saga

import { all, fork, put, delay, takeLatest } from 'redux-saga/effects'
import axios from 'axios'

import {
  LOG_IN_REQUEST, LOG_IN_SUCCESS, LOG_IN_FAILURE,
  LOG_OUT_REQUEST, LOG_OUT_SUCCESS, LOG_OUT_FAILURE,
  SIGN_UP_REQUEST, SIGN_UP_SUCCESS, SIGN_UP_FAILURE
} from '../reducers/user'

function logInAPI (data) {
  return axios.post('/api/login', data)
}
function* logIn (action) {
  try {
    console.log('saga login')
    // const result = yield call(logInAPI, action.data)
    yield delay(1000)
    yield put({
      type: LOG_IN_SUCCESS,
      data: action.data
    })
  } catch (err) {
    console.error(err)
    yield put({
      type: LOG_IN_FAILURE,
      error: err.response.data
    })
  }
}

function logOutAPI (data) {
  return axios.post('/api/logout', data)
}
function* logOut (action) {
  try {
    // const result = yield call(logOutAPI, action.data)
    yield delay(1000)
    yield put({
      type: LOG_OUT_SUCCESS
      // data: result.data
    })
  } catch (err) {
    yield put({
      type: LOG_OUT_FAILURE,
      error: err.response.data
    })
  }
}

function signUpAPI (data) {
  return axios.post('/api/logout', data)
}
function* signUp (action) {
  try {
    // const result = yield call(logOutAPI, action.data)
    yield delay(1000)
    yield put({
      type: SIGN_UP_SUCCESS
      // data: result.data
    })
  } catch (err) {
    yield put({
      type: SIGN_UP_FAILURE,
      error: err.response.data
    })
  }
}

function* watchLogIn () {
  yield takeLatest(LOG_IN_REQUEST, logIn)
}
function* watchLogOut () {
  yield takeLatest(LOG_OUT_REQUEST, logOut)
}
function* watchSignUp () {
  yield takeLatest(SIGN_UP_REQUEST, signUp)
}

export default function* userSaga() {
  yield all ([
    fork(watchLogIn),
    fork(watchLogOut),
    fork(watchSignUp)
  ])
}

configureStore.js

import { createWrapper } from 'next-redux-wrapper'
import { applyMiddleware, createStore, compose } from 'redux'
import { composeWithDevTools } from 'redux-devtools-extension'
import rootReducer from '../reducers';
import createSagaMiddleware from 'redux-saga'


import rootSaga from '../sagas';

const loggerMiddlware = ({dispatch, getState}) => (next) => (action) => {
  console.log(action)

  return next(action)
}

const configureStore = () => {
  const sagaMiddleware = createSagaMiddleware()
  const middlewares = [sagaMiddleware, loggerMiddlware];
  const enhancer = process.env.NODE_ENV === 'production'
  ? compose(applyMiddleware(...middlewares))
  : composeWithDevTools(applyMiddleware(...middlewares))

  const store = createStore(rootReducer, enhancer);
  store.sagaTask = sagaMiddleware.run(rootSaga)
  return store;
 
}

const wrapper = createWrapper(configureStore, {
  debug: process.env.NODE_ENV === 'development'
})

export default wrapper

usersaga나 configureStore도 잘 설정되 있는데 무엇이 문제인가 여 ㅜ

 

답변 2

0

ADD_POST_REQUEST 선언 하실때 export 안 붙여서 생기는 에러  같네요.

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

오, 이거인 것 같습니다.

문종현님의 프로필 이미지
문종현
질문자

아...정말 바보같은 실수를 했네요...ㅋㅋ 감사합니다!! 

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

리덕스 데브툴즈에서 LOG_IN_SUCCESS까지 호출되는지 봐보시고, reducers에서 해당 액션 코드도 봐보세요.

문종현님의 프로필 이미지
문종현
질문자

리덕스 데브툴즈에서 LOG_IN_REQUEST까지만 찍히네요 ㅜ

user saga쪽에도 console.log(saga login)도 찍히지 가 않구요 ㅜ

 

user reducer

const dummyUser = (data) => ({
  ...data,
  nickname: 'Moon',
  id: 1,
  Posts: [],
  Followings: [],
  Followers: [],
})

export const loginRequestAction = (data) => ({

    type: LOG_IN_REQUEST,
    data,
 
})

export const logoutRequestAction = (data) => ({
    type: LOG_OUT_REQUEST,
})

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case LOG_IN_REQUEST:
      console.log('reduce login')
      return {
        ...state,
        loginLoading : true,
        logInError: null,
        loginDone: false
      }
    case LOG_IN_SUCCESS:
      console.log(me)
      return {
        ...state,
        loginLoading: false,
        loginDone: true,
        me: dummyUser(action.data)
      }
    case LOG_IN_FAILURE:
      return {
        ...state,
        loginLoading: false,
        logInError: action.error,
      }
    case LOG_OUT_REQUEST:
      return {
        ...state,
        logoutLoading: true,
        logoutDone: false,
        logoutError: null,
      }
    case LOG_OUT_SUCCESS:
      return {
        ...state,
        logoutLoading: false,
        logoutDone: true,
        me: null
      }
    case LOG_OUT_FAILURE:
      return {
        ...state,
        logoutLoading: false,
        logoutError: action.error
      }
    case SIGN_UP_REQUEST:
      return {
        ...state,
        signUpLoading: true,
        signUpDone: false,
        signUpError: null,
      }
    case SIGN_UP_SUCCESS:
      return {
        ...state,
        signUpLoading: false,
        signUpError: action.error,
      }
    case SIGN_UP_FAILURE:
      return {
        ...state,
        signUpLoading: false,
        signUpError: action.error
      }
    case CHANGE_NICKNAME_REQUEST:
      return {
        ...state,
        changeNicknameLoading: true,
        changeNicknameDone: false,
        changeNicknameError: null,
      }
    case CHANGE_NICKNAME_SUCCESS:
      return {
        ...state,
        ChangeNicknameLoading: false,
        ChangeNicknameDone: true,
      }
    case CHANGE_NICKNAME_FAILURE:
      return {
        ...state,
        ChangeNicknameLoading: false,
        ChangeNicknameError: action.error
      }
    default:
      return state;
  }
}

여기에도 잘못된 부분은 없는거 같은데 왜 사가쪽이 호출이 안돼는지 모르겠습니다 ㅜ

 

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

에러메시지 상에는 watchAddPost가 문제라고 되어있습니다.

문종현님의 프로필 이미지
문종현
질문자

아 그렇군요 watchAddPost코드를 보고있는데 무엇이 잘못된건지 모르겠습니다 ㅜ

import { all, fork, put, delay, takeLatest } from 'redux-saga/effects'
import axios from 'axios'

import {ADD_POST_REQUEST, ADD_POST_FAILURE, ADD_POST_SUCCESS, ADD_COMMENT_FAILURE, ADD_COMMENT_REQUEST, ADD_COMMENT_SUCCESS} from '../reducers/post'

function addPostAPI (data) {
  return axios.post('/api/addPost', data)
}
function* addPost (action) {
  try {
    // const result = yield call(addPostAPI, action.data)
    yield delay(1000)
    yield put({
      type: ADD_POST_SUCCESS
      // data: result.data
    })
  } catch (err) {
    yield put({
      type: ADD_POST_FAILURE,
      data: err.response.data
    })
  }
}

function addCommentAPI (data) {
  return axios.post('/api/addPost', data)
}
function* addComment (action) {
  try {
    // const result = yield call(addPostAPI, action.data)
    yield delay(1000)
    yield put({
      type: ADD_COMMENT_SUCCESS
      // data: result.data
    })
  } catch (err) {
    yield put({
      type: ADD_COMMENT_FAILURE,
      data: err.response.data
    })
  }
}

function* watchAddPost () {
  yield takeLatest(ADD_POST_REQUEST, addPost)
}

function* watchAddComment () {
  yield takeLatest(ADD_COMMENT_REQUEST, addComment)
}

export default function* postSaga() {
  yield all ([
    fork(watchAddPost),
    fork(watchAddComment)
  ])
}

강의도 돌려보고 깃헙 코드도 보고있는데 무엇이 잘못된건지 모르겠습니다 ㅜ

 

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

rootSaga쪽은요?

일단 무조건 saga 코드쪽에 있습니다. 에러메시지가 저렇게 난다면요.

문종현님의 프로필 이미지
문종현
질문자

rootSaga쪽은 사실 처음에 설정한 이후 만진적이 없어서

import { all, fork } from 'redux-saga/effects'

import postSaga from './post'
import userSaga from './user'

export default function* rootSaga () {
  yield all([
    fork(userSaga),
    fork(postSaga)
  ])
}

그래도 첨부해드리곘습니다 ㅜ

저도 혼자 계속 보고있긴한데 도움을 주시면 감사하겠습니다!

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

에러의 원인 코드를 잘 찾아보세요. fork(postSaga)를 뺐을 때 정상작동한다하면 fork(postSaga)가 문제이겠죠? 이런 식으로요.

문종현님의 프로필 이미지
문종현
질문자

감사합니다. fork(postSaga)를 빼면 정상작동 합니다.

그래서 fork(postSaga)가 문제인데 sagas/post.js 를 계속 살펴보고있는데 도대체 무슨 이유인지 모르겠네요 ㅜㅜ sagas/post.js의 어떤 부분이 잘못 되있는지 봐주실수 있나요?ㅜ

문종현님의 프로필 이미지
문종현
질문자

post saga를 설정하는 전전 강의 부터 다시 들으며 진행중에 있는데 뭘 잘못 설정했는지 찾지 못했습니다 ㅜ 어디가 잘못된 것일가요 ㅜ 

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

reducers/post.js에서 ADD_POST_REQUEST 같은 문자열에 오타 없나요?

문종현님의 프로필 이미지
문종현
질문자

예 ㅜㅜ 가장먼저 살펴봤는데 그부분의 오타는 없는듯 보입니다

reducers/post.js

export const initialState = {
  mainPosts: [{
    id: 1,
    User: {
      id: 1,
      nickname: 'moon'
    },
    content: '첫번째 게시글 #해시태그 #응가',
    Images: [{
        src: 'https://bookthumb-phinf.pstatic.net/cover/137/995/13799585.jpg?udate=20180726'
      }, {
        src: 'https://gimg.gilbut.co.kr/book/BN001958/rn_view_BN001958.jpg'
      }, {
        src: 'https://gimg.gilbut.co.kr/book/BN001998/rn_view_BN001998.jpg'
      }],
      Comments: [{
        User: {
          nickname: '소변'
        },
        content: '소변 마려워요'
      }, {
        User: {
          nickname: '똥'
        },
        content: '똥 마려워요'
      }],
     
  }],
  imagePath: [],
  addPostLoading: false,
  addPostDone: false,
  addPostError: null,
  addCommentLoading: false,
  addCommentDone: false,
  addCommentError: null,
}

const ADD_POST_REQUEST = "ADD_POST_REQUEST";
const ADD_POST_SUCCESS = "ADD_POST_SUCCESS";
const ADD_POST_FAILURE = "ADD_POST_FAILURE";

const ADD_COMMENT_REQUEST = "ADD_COMMENT_REQUEST";
const ADD_COMMENT_SUCCESS = "ADD_COMMENT_SUCCESS";
const ADD_COMMENT_FAILURE = "ADD_COMMENT_FAILURE";

export const addPost = (data) => ({
  type: ADD_POST_REQUEST,
  data,
})

export const addComment = (data) => ({
  type: ADD_COMMENT_REQUEST,
  data,
})

const dummyPost = {
  id: 2,
  content: '더미데이터입니다.',
  User: {
    id: 2,
    nickname: '제로초',
  },
  Images: [],
  Comments: [],
}

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case ADD_POST_REQUEST:
      return {
        ...state,
        addPostLoading: true,
        addPostDone: false,
        addPostError: null
      }
    case ADD_POST_SUCCESS:
      return {
        ...state,
        mainPosts: [dummyPost, ...state.mainPosts],
        addPostLoading: false,
        addPostDone: true
      }
    case ADD_POST_FAILURE:
      return {
        ...state,
        addPostLoading: false,
        addPostError: action.error
      }
    case ADD_COMMENT_REQUEST:
      return {
        ...state,
        addCommentLoading: true,
        addCommentDone: false,
        addCommentError: null
      }
    case ADD_COMMENT_SUCCESS:
      return {
        ...state,
        addCommentLoading: false,
        addCommentDone: true
      }
    case ADD_COMMENT_FAILURE:
      return {
        ...state,
        addCommentLoading: false,
        addCommentError: action.error
      }
    default:
      return state;
  }
}

export default reducer

참고용 코드 올려드립니다

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

오타가 눈에는 보이지 않네요. 여기까지 도와드렸으면 나머지는 직접 해결하실 수 있을 거라고 생각합니다. 직접 해결하셔야 하고요. 제가 에러 위치 찾는 방법을 다 알려드렸으니까요.

문종현님의 프로필 이미지
문종현
질문자

아 정말 바보같은 실수를 했네요... 액션 export를 안하고 진행을 했네요!

계속 답변해주시고 길 알려주셔서

정말 감사합니다~~~!!^^

문종현님의 프로필 이미지
문종현

작성한 질문수

질문하기