새로고침이 될 때 마다 리덕스 스토어가 초기화되고 있다ㅠ 그로 인해 로그인이 해제되는데, 어떻게 해결할 수 있을까?
간단한 방법으로는 로컬 스토리지에 쿠키를 넣어주는 방법이 있다. 그러나 이미 nodeJS에 passport를 사용하고 있기 때문에, 이를 활용해보도록 한다.
서버 측에서는 로그인을 했을 때, passport를 통해 User 세션을 유지하고 있다.
따라서 새로고침할 때 마다 useEffect를 통해 dispatch를 해서, 서버의 User 세션을 받아오도록 한다.
코드 구현
부모 컨포넌트 측 ⇒ useEffect 추가
useEffect(() => {
dispatch({
type: LOAD_MY_INFO_REQUEST,
});
}, []);
리덕스에도 액션 추가해주고, 성공시 action.data를 initialState에 넣도록 한다.
// .. initialState
export const initialState = {
loadMyInfoLoading: false, // 유저 정보 가져오기 시도중
loadMyInfoDone: false,
loadMyInfoError: null,
}
// ..액션 함수
export const LOAD_MY_INFO_REQUEST = 'LOAD_MY_INFO_REQUEST';
export const LOAD_MY_INFO_SUCCESS = 'LOAD_MY_INFO_SUCCESS';
export const LOAD_MY_INFO_FAILURE = 'LOAD_MY_INFO_FAILURE';
// ..immer을 통한 액션 생성 함수
const reducer = (state = initialState, action) => produce(state, (draft) => {
switch (action.type) {
case LOAD_MY_INFO_REQUEST:
draft.loadMyInfoLoading = true;
draft.loadMyInfoError = null;
draft.loadMyInfoDone = false;
break;
case LOAD_MY_INFO_SUCCESS:
draft.loadMyInfoLoading = false;
draft.me = action.data;
draft.followDone = true;
break;
case LOAD_MY_INFO_FAILURE:
draft.loadMyInfoLoading = false;
draft.loadMyInfoError = action.error;
break;
//...
}
사가에도 함수들을 추가해준다.
function loadMyInfoAPI() {
return axios.get('/user');
}
function* loadMyInfo(action) {
try {
const result = yield call(loadMyInfoAPI, action.data);
yield put({
type: LOAD_MY_INFO_SUCCESS,
data: result.data,
});
} catch (err) {
console.error(err);
yield put({
type: LOAD_MY_INFO_FAILURE,
error: err.response.data,
});
}
}
//..
function* watchLoadMyInfo() {
yield takeEvery(LOAD_MY_INFO_REQUEST, loadMyInfo);
}
//..
export default function* userSaga() {
yield all([
fork(watchLoadMyInfo),
//..
]);
}
노드js에도 router를 추가해준다.
// routes/user
//...
// loadMyInfo
router.get('/', async (req, res, next) => { // GET /user
try {
if (req.user) {
const fullUserWithoutPassword = await User.findOne({
where: { id: req.user.id },
attributes: {
exclude: ['password']
},
})
res.status(200).json(fullUserWithoutPassword);
} else {
res.status(200).json(null);
}
} catch (error) {
console.error(error);
next(error);
}
});
후후.. 이제 잘 된다.
출처: [리뉴얼] React로 NodeBird SNS 만들기, 제로초