user.js 4.68 KB
import {all, call, fork, delay, put, takeEvery, takeLatest} from 'redux-saga/effects';
import axios from 'axios';
import host from '../env';
import {
    LOG_IN_FAILURE,
    LOG_IN_REQUEST,
    LOG_IN_SUCCESS,

    SIGN_UP_FAILURE,
    SIGN_UP_REQUEST,
    SIGN_UP_SUCCESS,

    LOAD_ME_REQUEST,
    LOAD_ME_SUCCESS,
    LOAD_ME_FAILURE,

    LOG_OUT_REQUEST,
    LOG_OUT_SUCCESS,
    LOG_OUT_FAILURE,
} from '../reducers/user';
import {AsyncStorage} from 'react-native';

const parseCookies = (cookies = '') =>
    cookies
        .split(';')
        .map(v =>
            v.split('=')
        )
        .reduce((acc, [key, value]) => {
            acc[key.trim()] = decodeURIComponent(value);
            console.log(acc);
            return acc;
        }, {});

//로그인
function loginAPI(data) {
    const {email, password} = data;
    console.log(email, password);
    console.log(`http://${host}:4001/user/login`);
    // const res1 = axios.get(`http://${host}:4001/user/test`, {
    //     withCredentials: true
    // });
    return axios.post(`http://${host}:4001/user/login`, {
        email, password
    }, {
        withCredentials: true
    });
}

// # 함수의 동기적인 호출을 할 때 사용
// 응답이 다 받아진 후에 실행할 때 사용
function* login(action) {
    try {
        console.log('login하러 왔어요');
        const res = yield call(loginAPI, action.data);
        console.log('서버 login에서 온 응답', res);
        const {user} = res.data;
        const cookieArray = res.headers['set-cookie'];
        console.log(cookieArray);
        yield call(AsyncStorage.setItem, 'cookie', `userChecker=s%3A${cookieArray.map(cookie => parseCookies(cookie)['userChecker'].substring(2))}`);
        yield put({
            type: LOG_IN_SUCCESS,
            data: {
                me: user
            }
        })
    } catch (e) {
        console.error(e);
        yield put({
            type: LOG_IN_FAILURE,
            data: {
                info: e.response.data.info
            }
        })
    }
};

function* watchLogin() {
    yield takeLatest(LOG_IN_REQUEST, login);
}

// 회원가입
function signUpAPI(data) {
    const {email, nickName, password} = data;
    return axios.post(`http://${host}:4001/user/signUp`, {
        email, nickName, password
    }, {
        withCredentials: true
    });
}

function* signUp(action) {
    try {
        console.log('signUp 실행원할');
        const res = yield call(signUpAPI, action.data);
        const {me} = res.data;
        yield put({
            type: SIGN_UP_SUCCESS,
            data: {
                me
            }
        });
    } catch (e) {
        console.error(e);
        yield put({
            type: SIGN_UP_FAILURE,
            data: {
                info: e.response.data.info
            }
        });
    }
}

// # generator 함수에서 마지막 액션 하나만 유효하다고 인정
// 실수로 회원가입 버튼을 연달아 누를 경우 서버의 요청이 2번 가지 않게함
function* watchSignUp() {
    yield takeLatest(SIGN_UP_REQUEST, signUp);
}


function loadMeAPI() {
    return axios.get(`http://${host}:4001/user/loadMe`, {withCredentials: true})
};

function* loadMe(action) {
    try {
        console.log('loadMe 실행원할');
        const res = yield call(loadMeAPI, action.data);
        const {user} = res.data;
        yield put({
            type: LOAD_ME_SUCCESS,
            data: {
                user
            }
        })
    } catch (e) {
        console.error(e);
        yield put({
            type: LOAD_ME_FAILURE,
            data: {
                info: e.response.data.info
            }
        })
    }
};

function* watchLoadMe() {
    yield takeLatest(LOAD_ME_REQUEST, loadMe);
}

function logoutAPI() {
    return axios.get(`http://${host}:4001/user/logout`, {withCredentials: true});
}

function* logout() {
    try {
        const res = yield call(logoutAPI);
        console.log('logout 완료');
        yield call(AsyncStorage.removeItem, 'cookie');
        yield put({
            type: LOG_OUT_SUCCESS
        });
    } catch (e) {
        console.error(e);
        yield put({
            type: LOG_OUT_FAILURE,
            data: {
                info: e.response.data.info
            }
        })
    }
}

function* watchLogoutMe() {
    yield takeLatest(LOG_OUT_REQUEST, logout);
}

// # 모든 액션을 유효하게 인정한다.
// while(true)로 감싸는 효과
// takeEvery

// # 함수의 비동기적인 호출을 사용할 때
// call과 다르게 fork는 순서 상관없이 실행할 때 사용
export default function* userSaga() {
    yield all([
        fork(watchLogin),
        fork(watchSignUp),
        fork(watchLoadMe),
        fork(watchLogoutMe),
    ]);
}