본문 바로가기

Web Dev/react.js

React - Redux Toolkit 사용하여 Login 정보 store에 저장해서 필요할 때 사용하는 방법 !

반응형

https://ko.redux.js.org/introduction/getting-started/

https://hanamon.kr/redux%EB%9E%80-%EB%A6%AC%EB%8D%95%EC%8A%A4-%EC%83%81%ED%83%9C-%EA%B4%80%EB%A6%AC-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC/

 

Redux(리덕스)란? (상태 관리 라이브러리) - 하나몬

Redux(리덕스)란? 무엇인지 부터 간단한 실습까지 (상태 관리 라이브러리 리덕스 알아보기) ⚡️ Redux(리덕스)란? Redux(리덕스)란 JavaScript(자바스트립트) 상태관리 라이브러리이다. Redux(리덕스)의

hanamon.kr

이 분 블로그 너무 잘 설명 되어있습니다. 

 

Redux 시작하기 | Redux

소개 > 시작하기: Redux를 배우고 사용하기 위한 자료

ko.redux.js.org

리덕스 에서 

리덕스 툴킷을 설치하고 사용하기를 권장하고 있습니다. 

# NPM
npm install @reduxjs/toolkit

# Yarn
yarn add @reduxjs/toolkit
npm install react-redux

https://ko.redux.js.org/tutorials/quick-start/#install-redux-toolkit-and-react-redux

 

Quick Start | Redux

- How to set up and use Redux Toolkit with React-Redux

ko.redux.js.org

npm install @reduxjs/toolkit react-redux

https://ko.redux.js.org/tutorials/quick-start/

 

Quick Start | Redux

- How to set up and use Redux Toolkit with React-Redux

ko.redux.js.org

해당 Quick Start 를 참고 하시면 되겠습니다. 

제 코드를 예시로 보여드리겠습니다.

저는 일단 로그인에 쓰기위한 userSlice를 만들었습니다. 

src > Reducer 

 userSlice.js

import { createSlice } from "@reduxjs/toolkit";

export const userSlice = createSlice({
    name: "user",
    initialState: {

        displayName: "",
        uid: "",
        accessToken: "",
    },
    reducers: {
        loginUser: (state) => {

            // state.value += 1;
        },
        clearUser: (state) => {
            state.value = "";
        },

    }
});

export const { loginUser, clearUser } = userSlice.actions;

export default userSlice.reducer;

store.js

import { configureStore } from '@reduxjs/toolkit'
import userSlice from './userSlice'

export default configureStore({
    reducer: {
        user: userSlice,
    }
})

 

App.js

import { useSelector, useDispatch } from 'react-redux';
import { loginUser, clearUser } from './Reducer/userSlice';
import firebase from './firebase';

위의 내용을 import 해줍니다. 

useEffect 을 통해 로그인 할 때 정보를 useInfo 변수를 통해 찍어 줘 봅니다.

App.js

  useEffect(() => {
    // 로그인이나 로그아웃을 하면 값 확인 , 그외에는 값 null
    firebase.auth().onAuthStateChanged((userInfo) => {
      console.log('userInfo : ', userInfo)
    })

  }, [])

  useEffect(() => {
    // 로그 아웃
    // firebase.auth().signOut();

  }, [])

해당 값을 필요한 값을 보내주고 

또 가져오고 ! 

App.js

  const dispatch = useDispatch();
  //저장 되어 있는  state를 가져올 수 있다
  const user = useSelector(state => state.user)

  useEffect(() => {
    // 로그인이나 로그아웃을 하면 값 확인 , 그외에는 값 null
    firebase.auth().onAuthStateChanged((userInfo) => {

      if (userInfo) {
        //보낸다 -> store 
        dispatch(loginUser(userInfo.multiFactor.user));
      }
    })

  }, [])

  useEffect(() => {

    console.log("user : " + user)

  }, [user])


  useEffect(() => {
    // 로그 아웃
    // firebase.auth().signOut();

  }, [])

하니까 뭐 값을 못 읽는다 하면서 에러가 나서

에러 발생

serializableStateInvariantMiddleware.ts:234 A non-serializable value was detected in an action, in the path: `payload`. Value: UserImpl {providerId: 'firebase', proactiveRefresh: ProactiveRefresh, reloadUserInfo: null, uid: 'b3xyOksQ7YfTYVl7onZZhsbru213', reloadListener: ƒ, …} 
Take a look at the logic that dispatched this action:  {type: 'counter/loginUser', payload: UserImpl} 
(See https://redux.js.org/faq/actions#why-should-type-be-a-string-or-at-least-serializable-why-should-my-action-types-be-constants) 
(To allow non-serializable values see: https://redux-toolkit.js.org/usage/usage-guide#working-with-non-serializable-data)

 

데이터 원본 값이 너무 많으니까 정렬화 해서 필요한 데이터만 보내주는 게 

시스템상 과부하도 안 걸리고 좋겠지 ! 

 const dispatch = useDispatch();
  //저장 되어 있는  state를 가져올 수 있다
  const user = useSelector(state => state.user)

  function serializeUser(user) {
    return {
      displayName: user.displayName,
      uid: user.uid,
      accessToken: user.accessToken
      // ... serialize other necessary properties
    };
  }


  useEffect(() => {
    // 로그인이나 로그아웃을 하면 값 확인 , 그외에는 값 null
    firebase.auth().onAuthStateChanged((userInfo) => {
      if (userInfo) {
        const serializedUser = serializeUser(userInfo.multiFactor.user);
        console.log(serializedUser)

        // //보낸다 -> store 
        dispatch(loginUser(serializedUser));
      }

    })

  }, [])

  useEffect(() => {

    console.log("user : " + user)

  }, [user])

 

사실 이게 계속 데이터 값 정렬화 해야된다고 생각하고 위와 같은 코드를 추가적으로 작성한건데 

알고 보니 내가 전에 연습한다고 store.js  파일을 두개 만들어 놓아서 

생긴 일이 였다. 

데이터 정렬화를 했더니 에러메세지는 없어졌지만

코드를 아무리 확인해봐도 undefined 라고 떠서 

고민이였는데 store.js 파일이 두개여서 어디로 보내야하는지 모르는 상황이였나보다 

그래서 하나로 통합해줬더니 문제 없이 잘 진행된다. 

store.js

import { configureStore } from '@reduxjs/toolkit'
import counterSlice from '../Reducer/counterSlice'
import userSlice from '../Reducer/userSlice'

export default configureStore({
    reducer: {
        counter: counterSlice,
        user: userSlice,
    }
})

 로그인 전 값이 들어오지 않는다 ! 

꼭 데이터 정렬화 해주도록하자 

기분 나쁘게 에러 메세지 계속 뜬다 

해당 에러를 그냥 아예 무시하는 방법도 있다는데 ... 

store.js

import { configureStore } from '@reduxjs/toolkit'
import counterSlice from '../Reducer/counterSlice'
import userSlice from '../Reducer/userSlice'

export default configureStore({
    reducer: {
        counter: counterSlice,
        user: userSlice,
    },
    middleware: (getDefaultMiddleware) =>
        getDefaultMiddleware({
            serializableCheck: false,
        })
})

이렇게 middleware를 추가로 입력해주면된다는데... 

좋은 방법인지는 모르겠다. 

여튼 위의 코드를 통해서 유저 접속 정보를 

Redux store에 저장하였고 

필요할때 마다 해당 값을 

const user = useSelector((state) => state.user)

통해 내려 받아서 사용하기만 하면 된다. 

반응형