• 카테고리

    질문 & 답변
  • 세부 분야

    풀스택

  • 해결 여부

    미해결

Redux-Saga Login_REQUEST 문제입니다.

23.11.29 14:03 작성 23.11.29 14:03 수정 조회수 269

0

redux-saga 쪼개고 reducer 연결 하려고 하니 user reducer만 반응하고 LOG_IN_SUCCESS 는 반응을 하지 않습니다.
커뮤니티 게시판에서 여러가지를 확인해보고 해도 어디 부분이 잘못 된지 몰라 올려봅니다..

제가 작성한 코드는 이러합니다.

store/configureStore.js


import { applyMiddleware, createStore, compose } from "redux";
import createSagaMiddleware from "redux-saga";
import { createWrapper } from "next-redux-wrapper";
import { composeWithDevTools } from "redux-devtools-extension";
import reducer from "../reducers";
import rootSaga from "../sagas";


const configureStore = (context) => {
  console.log("context", context);
  const sagaMiddleware = createSagaMiddleware();
  const middlewares = [sagaMiddleware];

  const enhancer =
    process.env.NODE_ENV === "production"
      ? compose(applyMiddleware(...middlewares)) // 배포용
      : composeWithDevTools(applyMiddleware(...middlewares));
  

  const store = createStore(reducer, enhancer);


  store.sagaTask = sagaMiddleware.run(rootSaga);

  return store;
};

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

export default wrapper;

reducers/index.js

 

import { HYDRATE } from "next-redux-wrapper"; // HYDRATE = action
import { combineReducers } from "redux";

import user from "./user";
import post from "./post";

const rootReducer = combineReducers({
  index: (state = {}, action) => {
    switch (action.type) {
      case HYDRATE:
        console.log("HYDRATE", action);
        return { ...state, ...action.payload };
      default:
        return state;
    }
  },
  user,
  post,
});

export default rootReducer;

 

reducers/user.js

 

export const initialState = {
  isLoggingIn: false, // 로그인 시도중
  isLoggedIn: false, // 로그인
  isLoggingOut: false, // 로그아웃 시도중
  meUser: null,
  signUpData: {},
  loginData: {},
};

export const LOG_IN_REQUEST = "LOG_IN_REQUEST";
export const LOG_IN_SUCCESS = "LOG_IN_SUCCESS";
export const LOG_IN_FAILURE = "LOG_IN_FAILURE";

export const LOG_OUT_REQUEST = "LOG_OUT_REQUEST";
export const LOG_OUT_SUCCESS = "LOG_OUT_SUCCESS";
export const LOG_OUT_FAILURE = "LOG_OUT_FAILURE";

export const loginRequestAction = (data) => ({
  type: LOG_IN_REQUEST,
  value: data,
});

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

const reducer = (state = initialState, action) => {
  // prettier-ignore
  switch(action.type) {
    case LOG_OUT_REQUEST : return {...state, isLoggingIn : true}; 
    case LOG_IN_SUCCESS :  return {...state, isLoggingIn : false, isLoggedIn:true, meUser:{...action.value, nickName:"Jay"}};
    case LOG_IN_FAILURE :  return {...state,  isLoggingIn : false, isLoggedIn:false };

    case "LOG_OUT_REQUEST" : return {...state,  isLoggingOut:true};
    case "LOG_OUT_SUCCESS" : return {...state,  isLoggingOut:false, isLoggedIn:true, meUser:null};
    case "LOG_OUT_FAILURE" : return {...state,  isLoggingOut:false};


    default: return state;
  }
};
export default reducer;

sagas/index.js

import { all, fork, call } from "redux-saga/effects";

import userSaga from "./user";



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

sagas/user.js

 

import { all, fork, put, delay, takeLatest } from "redux-saga/effects";
import {
  LOG_IN_FAILURE,
  LOG_IN_REQUEST,
  LOG_IN_SUCCESS,
} from "../reducers/user";



function* logIn(action) {
  try {
    console.log("saga logIn");
    // const result = yield call(logInAPI);
    yield delay(1000);
    yield put({
      type: LOG_IN_SUCCESS,
      value: action.value,
    });
  } catch (err) {
    console.error(err);
    yield put({
      type: LOG_IN_FAILURE,
      error: err.response.data,
    });
  }
}

function* watchLogIn() {
  yield takeLatest(LOG_IN_REQUEST, logIn);

}

function* watchLogOut() {
  yield takeLatest("LOG_OUT_REQUEST");
}

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

답변 2

·

답변을 작성해보세요.

0

다른 사가도 하나 만들어서 임의로 dispatch 한 번 해보세요.

function* logOut() {
  try {
    // const result = yield call(logOutAPI);
    yield delay(1000);
    yield put({
      type: LOG_OUT_SUCCESS,
    });
  } catch (err) {
    console.error(err);
    yield put({
      type: LOG_OUT_FAILURE,
      error: err.response.data,
    });
  }
}

watchLogOut 에서 위를 만들어 주지 않아 문제가 생겼던 것 같습니다...
해결되었습니다.
함께 봐주셔서 감사합니다

0

sagas/index.js에 postSaga 안 넣으셨네요

user 로그인부터 redux를 확인하고 post를 실행 하려고 했는데 혹시 Post 를 빼면 안되는걸까요...?

무슨 말씀이신지 이해가 안 되네요

질문이 민망했네요...
userSaga만 넣고 로그인만 확인 하고 싶었는데, LOG_IN_REQUEST 만 반응을 하여 질문을 올렸습니다.

그리고 postSaga를 넣어야지만 반응을 하는지에 대해서 추가 적으로 여쭤 본 것이고요.

아, 저도 헷갈렸습니다. saga login 콘솔 로그부터가 안 찍히시는 건가요?

일단 reducer에는 LOG_IN_REQUEST가 없네요.

reducers/user.js 의 reducer에서는 로그 찍히는 걸 확인 하였고,

sagas/user.js 에서

function* watchLogIn() {
  console.log("확인");
  yield takeLatest(LOG_IN_REQUEST, logIn);
}

여기 부분까지는 log가 나오고

여기부분의 saga logIn log는 찍히지 않습니다.

function* logIn(action) {
  try {
    console.log("saga logIn");
    // const result = yield call(logInAPI);
    yield delay(1000);
    yield put({
      type: LOG_IN_SUCCESS,
      value: action.value,
    });
  } catch (err) {
    console.error(err);
    yield put({
      type: LOG_IN_FAILURE,
      error: err.response.data,
    });
  }
}



image

redux devTools 의 반응은 이렇게 나오고 있으며,

추가적으로
pages/_app.js 하이엔드로 감싼 내용입니다.

import PropTypes from "prop-types";
import Head from "next/head"; 
import wrapper from "../store/configureStore";

const App = ({ Component }) => {
  return (
    <>
      <Head>
        <meta charSet="utf-8" />
        <title>NodeBird</title>
      </Head>
      <Component />
    </>
  );
};

App.propTypes = {
  Component: PropTypes.elementType.isRequired,
};


export default wrapper.withRedux(App);


일단 watchLogIn에 콘솔이 찍히는 걸 보니 saga는 연결이 제대로 된 것인데, 그 뒤에는 오타가 눈에 보이지 않네요. 이게 연결이 잘 안 된 것이 분명하긴 합니다.

LOG_IN_REQUEST 부분으로 수정하고 해보았는데 redux부분에서 아까와는 다르게 isLoggingIn 이 true 로 바뀌어 희망을 보았습니다.
하지만 계속 saga login 의 로그는 찍히지 않네요..
연결 또는 다른 오타가 있는지 계속 찾아보겠습니다..

userSaga에 있는 fork(watchLogOut) 을 주석 처리를 하니 logIn이 잘 실행됩니다...

아.. watchLogOut에서 takeLatest에 함수가 없네요..