먼저 Redux의 개념은 이러함.
React에서는 state라는 존재. 말 그대로 어떠한 상태.
그 상태를 조작하기 위해 훅을 사용했음.
그런데 그 state를 선언한 컴포넌트 외에 다른 곳에서도 쓰고 싶음. 그럴려면 props를 활용해서 넘겨주면 됐음.
여기서 문제 상황.
만약 자식 컴포넌트가 100개라면?
일일이 props로 다 넘겨주다가 손가락 나갈 듯.
그래서 react에는 context라는 개념을 활용해서 useContext라는 훅을 활용해 props로 넘겨주지 않고 state를 관리할 수 있는 방법을 만듦. 근데 이게 개복잡. 더 편한 방식이 바로 redux다.
원리는 조작할 변수나 함수를 다른 곳에 저장 후 내가 필요할 때마다 거기서 꺼내쓰는 방식이다.
비유하자면 어떤 동화를 입을 통해서 넘어넘어 알게 되는 방식이 아니라 도서관을 하나 만들어서 거기다가 넣어놓고 내가 필요할 때마다 책을 꺼내 쓰는 느낌이다.
일단 redux 공홈을 가보자.
npm으로 깔고 그 뒤에 counter를 활용한 예시가 있다.
이거는 정답지가 이미 나와있으므로 다른 예시로 연습을 해보자.
전역변수로 저장할만한 것들이 뭐가 있을까?
가장 간단한 걸로 생각한 거는 '로그인 여부'
로그인이 되야 뜰 수 있는 페이지와 항목들이 있고 로그아웃을 나타내고 아니면 입력창을 표시해줘야 한다.
그리고 그 상태는 100번 앞구르기해도 유지되어야 함.
먼저 store라는 폴더를 따로 만들어서 저장하고 싶은 애들을 파일로 만든다.
index.js가 전체적인 애들을 관리하는 애들, 나머지가 짜잘한 애들
redux의 기본 코드 형식은 아래와 같음.
import { createSlice } from "@reduxjs/toolkit";
const initialCounterState = { counter: 0, showCounter: true };
const counterSlice = createSlice({
name: "counter",
initialState: initialCounterState,
reducers: {
increment(state) {
state.counter++;
},
decrement(state) {
state.counter--;
},
incrementByAmount(state, action) {
state.counter += action.payload;
},
toggle(state) {
state.showCounter = !state.showCounter;
},
},
});
도서관에 넣어놓을 책 하나를 slice라고 부른다.
그래서 createSlice 안에 필요한 거는 3가지
이름, 초기상태, reducer 내용
reducers 항목은 object로 그 안에 state를 조작할 수 있는 여러가지 함수를 넣어주면 된다. 이게 책 내용에 해당하는 거임.
import { createSlice } from "@reduxjs/toolkit";
const initialAuthState = { isAuthenticated: false };
const authSlice = createSlice({
name: "authentication",
initialState: initialAuthState,
reducers: {
login(state) {
state.isAuthenticated = true;
},
logout(state) {
state.isAuthenticated = false;
},
},
});
응용해서 로그인으로 만들어봄.
처음 상태는 false
그 다음에 login을 실행하면 true로 바꿔준다.
너무 쉽고~
export const authActions = authSlice.actions;
export default authSlice.reducer;
그 다음에 이게 좀 헷갈리는 부분이다.
actions에 해당하는 부분은 slice에서 reducers에 해당하는 부분이다.
authActions는 조작하는 함수들의 모음집에 해당한다.
그리고 authSlice.reducer는 이따가 합체할 때 사용하기 위해 reducer 부분을 export하는 거다.
(이 부분은 당장 몰라도 뒤에 바로 알게 됨.)
index.js
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./counter";
import authReducer from "./auth";
const store = configureStore({
reducer: { counter: counterReducer, auth: authReducer },
});
export default store;
이게 책들을 합쳐준 도서관이 되는 것임.
store 변수에 configureStore라는 애로 도서관을 만들고 그 안에 reducer 목록을 object로 불러옴.
아까 export default 한 부분을 불러와서 이런 식으로 auth라는 key value에 들어가게 되는 것임.
이제 도서관을 만들었음.
그럼 꺼내 써야지.
import { useDispatch } from "react-redux/es/exports";
import { authActions } from "../store/auth";
const dispatch = useDispatch();
const LoginHandler = (event) => {
event.preventDefault();
dispatch(authActions.login());
};
<form onSubmit={LoginHandler}>
<button>Login</button>
</form>
여기서도 새로운 애들이 등장한다.
useDispatch라는 부분이다.
책의 내용에 적힌 함수들을 실행하는 과정을 dispatch라고 생각하면 됨.
위와 같은 방식으로 dispatch를 그냥 불러오고 dispatch 안에 원하는 함수를 넣으면 됨.
아까 위에서 authActions 안에 함수들의 모음집을 넣었으니 걔네들을 불러와서 dispatch에 원하는 거 넣으면 됨.
login 버튼을 누르면 책에 적혀져있던 login 함수를 불러와서 실행하게 되고 그러면 책의 isLogin 변수가 바뀜.
즉 로그인 상태가 책에 새로 저장된 것이다.
참 쉽죠?
만약에 그 로그인 상태를 활용하고 싶다.
당연히 가능.
import { useDispatch, useSelector } from "react-redux/es/exports";
import { authActions } from "../store/auth";
const isLogin = useSelector((state) => state.auth.isAuthenticated);
const dispatch = useDispatch();
const logoutHandler = () => {
dispatch(authActions.logout());
};
<li>{isLogin && <button onClick={logoutHandler}>Logout</button>}</li>
여기서는 useSelector라는게 등장한다.
책에서 원하는 상태 즉 state 값을 불러오는게 useSelector다.
현재의 도서관에서 auth라는 제목의 책에 isAuthenticated라는 state를 불러온 것이다.
아까 index.js 파일에서 auth : authReducer라고 책을 저장해준 것 기억함?
그거임.
현재 상태의 변수 state는 index에서 configureStore 한 애들 즉 도서관에 해당하는 것이다.
즉, 다시 한 번 정리하면 도서관에서 auth라는 책을 꺼내 isAuthenticated라는 변수 state를 불러온 것이다.
이제 이 상태를 활용해보자.
로그인이 되었다면 로그아웃할 수 있는 버튼이 등장해야함.
로그인이 안 되있으면 당연히 무쓸모.
그래서 저렇게 조건부로 걸면 끝.
그리고 마찬가지로 dispatch로 로그아웃 버튼 클릭하면 logout 함수 실행.
redux를 활용해서 react app에 사용해봤다.
물론 props를 활용하면 이 기능을 구현할 수 없는 건 아니다. 하지만 일일이 isLogin 변수를 props를 넣어주고 logout,login 함수 선언해서 실행해야한다. 그리고 그건 그 컴포넌트 안에서만 선언해줬기 때문에 또 필요하면 함수를 또 prop로 넘겨줘야함. 그리고 부모 컴포넌트로 보내는 것도 귀찮음.
하지만 redux를 사용하면 store에 원하는 변수, 함수 저장해놓고 필요할 때마다 컴포넌트 상관없이 그냥 꺼내서 쓰면 된다. 변수조작에 일일이 노가다를 하지 않아도 되는 것이 redux의 힘이지 않을까 싶음.
새롭게 배운 내용 정리해보자.
createSlice로 이름, 초기상태, reducers를 선언해서 책을 만들어줌.
걔네들을 내보내서 index.js에서 configureStore로 도서관을 만들어준다.
함수를 꺼내쓰고 싶으면 dispatch (얘는 불러오면 끝)
변수를 꺼내쓰고 싶으면 useSelector (얘는 도서관안에 책 참조번호랑 변수 이름까지 확인 필요)
그리고 맘껏 쓰면 됨.
'웹 > Redux' 카테고리의 다른 글
Redux를 활용하여 장바구니 만들어보기 (firebase도 곁들인...) (0) | 2022.08.11 |
---|