[Redux-toolkit] 기초 및 로그인 구현하기

이경은·2022년 11월 25일
0

1. Redux 란?

1.1. 개념

React의 상태 관리 라이브러리로, state가 컴포넌트에 종속되지 않습니다.

기존에는 state를 다른 컴포넌트로 넘겨주려면 props 형태로 전달해야 하고 직접 부모-자식 컴포넌트가 아니면 값을 넘겨주기 어려웠습니다. 하지만 redux를 사용하면 어느 곳에서도 같은 값을 가져와서 사용할 수 있게 됩니다.

redux는 프로젝트 루트레벨에서 store라는 곳에 state를 저장하고, 모든 컴포넌트는 store에 구독을 하면서 state와 그 state를 바꾸는 함수를 전달 받게 됩니다. 함수를 통해서 state가 변경되면 해당 state를 바라보는 컴포넌트가 모두 리렌더링되면서 값이 변경됩니다. 어느 위치에 있든 한 번에 상태를 변경할 수 있다는 것이 특징입니다.

2. Redux-toolkit 이란

Redux를 사용하기 위해서는 설치해야 하는 라이브러리가 많고, 사용이 복잡합니다. 이를 해결하기 위해서 redux에서 공식적으로 만든 redux-toolkit이라는 라이브러리가 나왔습니다.
지저분하게 다른 것들을 설치할 필요가 없고, 사용이 좀 더 편리합니다.

2.1. 설치

# yarn 설치
yarn add redux react-redux @reduxjs/toolkit

# npm 설치
npm install redux react-redux @reduxjs/toolkit

2.2. 사용법

이번에는 로그인 기능 구현에 redux를 사용했습니다. 로그인 하게 되면 user의 정보를 redux state에 저장하고 사용하도록 했습니다.
아래에는 로그인, 로그아웃, 정보 업데이트 구현하는 방법에 대해 설명합니다.

Redux 파일 구조

src 폴더 아래에 store라는 폴더를 만들고 아래에 폴더와 파일들을 생성했습니다.

reducer란?

store에 들어갈 state와 state를 바꿀 함수를 정의하는 곳입니다.

1) rootReducer 정의

// store/index.js
import { combineReducers } from 'redux';

// project import
import menu from './menu'; // 세부 reducer
import user from './user'; // 세부 reducer

const reducers = combineReducers({ menu, user });

export default reducers;

2) 세부 reducer 정의

createSlice

  • 기존에 redux에서 createReducer와 createAction이 하던 일을 같이 해준다.
  • 이를 사용하면 actions를 위한 js 파일을 따로 만들 필요가 없습니다.

세부 reducer에서는 state의 기본 값과 state를 변경시키는 함수에 대해서 정의합니다. login 은 payload로 값을 변경하도록 하는 함수이고, logout 은 기본 값으로 state를 변경하도록 합니다.
saveUserInfo 는 user 정보를 변경할 때 사용하는 함수로 username과 introduction 값만 변경합니다.

// store/reducers/user.js
import { createSlice } from '@reduxjs/toolkit';

const initialStateValue = { value: { isAuthorized: false, userId: '', username: '', introduction: '' } };

export const user = createSlice({
    name: 'user',
    initialState: { value: initialStateValue },
    reducers: {
        login: (state, action) => {
            state.value = action.payload;
        },
        logout: (state) => {
            state.value = initialStateValue;
        },
        saveUserInfo: (state, action) => {
            state.value.username = action.payload.username;
            state.value.introduction = action.payload.introduction;
        }
    }
});

export default user.reducer;

export const { login, saveUserInfo, logout } = user.actions;

3. index.js reducer 반영

index.js에 store 값을 넣어줘야 합니다. 아래처럼 Providerstore를 넣어서 App 컴포넌트를 감싸줍니다.

import { Provider as ReduxProvider } from 'react-redux';
import { store } from 'store';

const container = document.getElementById('root');
const root = createRoot(container);
root.render(
    <ReduxProvider store={store}>
        <BrowserRouter>
            <App />
        </BrowserRouter>
    </ReduxProvider>
);

4. 컴포넌트에서 redux 사용

아래는 로그인 컴포넌트의 일부입니다.
useDispatch를 사용해서 값을 변경할 수 있습니다. 앞에서 만들어둔 login 함수를 활용해서 값을 변경해줍니다.

// AuthLogin.js
import { useDispatch } from 'react-redux';
import { login } from 'store/reducers/user';

const AuthLogin = () => {
	const dispatch = useDispatch();
	
	// dispatch를 사용해서 state를 변경한다
	dispatch(
      login({
          isAuthorized: true,
          userId: values.id,
          username: result[0].username,
          introduction: result[0].introduction
      })
  );
};

아래는 user의 프로필 정보를 표시하는 컴포넌트의 일부입니다.
useSelector를 사용해서 user 정보를 가져옵니다. 로그아웃도 여기에서 구현했는데, 아래처럼 dispatch를 사용해서 user 정보를 초기화 합니다.

// Profile.js
import { useSelector, useDispatch } from 'react-redux';

const Profile = () => {
	// useSelector를 사용해서 state 값을 가져온다.
	const user = useSelector((state) => state.user.value);

	const userName = user.username;
  	const introduction = user.introduction;

	const handleLogout = async () => {
      dispatch(logout());
      navigate('/login');
  };
};

아래는 프로필 정보를 업데이트하는 컴포넌트의 일부입니다.
마찬가지로 dispatch를 사용해서 state를 변경해줍니다.

// EditProfile.jsx
import { useDispatch } from 'react-redux';
import { saveUserInfo } from 'store/reducers/user';

const EditProfile = () => {
	const dispatch = useDispatch();
	const handleSave = () => {
      dispatch(saveUserInfo({ username: userInfo.userName, introduction: userInfo.introduction }));
  };
};

참조
https://velog.io/@mael1657/Redux-toolkit%EC%9C%BC%EB%A1%9C-%EC%83%81%ED%83%9C%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0

https://kyounghwan01.github.io/blog/React/redux/redux-basic/#%E1%84%89%E1%85%A1%E1%84%8B%E1%85%AD%E1%86%BC%E1%84%92%E1%85%A1%E1%84%82%E1%85%B3%E1%86%AB-%E1%84%8B%E1%85%B5%E1%84%8B%E1%85%B2

profile
Web Developer

0개의 댓글