[패스트캠퍼스 수강 후기] 프론트엔드 인강 100% 환급 챌린지 46회차 미션 - 35강 Redux 사용할 준비, 모듈 만들기
Redux 사용할 준비
먼저 새로운 react 프로젝트를 만들고 리덕스를 설치해준다.
npx create-react-app learn-redux
yarn add redux
그리고 exercise.js 파일을 하나 만들고 index.js에 import시켜주고 리덕스에 대해 실습을 해보도록 하자. 아래와 같이 코드를 입력한다.
module/exercise.js
import { createStore } from "redux";
const initialState = {
counter: 0,
text: "",
list: [],
};
const INCREASE = "INCREASE"; //액션타입의 경우 대문자로
const DECREASE = "DECREASE";
const CHANGE_TEXT = "CHANGE_TEXT"; //액션타입의 경우 언더바로
const ADD_TO_LIST = "ADD_TO_LIST";
// function increase(){
// return {
// type: INCREASE
// }
// }
//아래와 같이 화살표 함수를 쓰면 return을 생략해줄 수 있다.
const increase = () => ({
//액션생성함수를 작성할때는 소문자로
type: INCREASE,
});
const decrease = () => ({
type: DECREASE,
});
const changeText = (text) => ({
//액션생성함수의 경우 카멜기법으로
type: CHANGE_TEXT,
text,
});
const addToList = (item) => ({
type: ADD_TO_LIST,
item,
});
function reducer(state = initialState, action) {
//state에 기본값을 넣어줌
switch (action.type) {
case INCREASE:
return {
...state,
counter: state.counter + 1,
};
case DECREASE:
return {
...state,
counter: state.counter - 1,
};
case CHANGE_TEXT:
return {
...state,
text: action.text,
};
case ADD_TO_LIST:
return {
...state,
list: state.list.concat(action.item),
};
default:
//state가 undefined라면 기본값 반환
return state;
}
}
const store = createStore(reducer);
console.log(store.getState());
const listener = () => {
//구독하는 것.
const state = store.getState();
console.log(state);
};
const unsubscribe = store.subscribe(listener);
//이게 왜 구독을 해제하는 거지?? 하 ㅉㅈ..
//unsubscribe(); 함수로 만든적도 없는애가 어떻게 생겨나는 거지?
//너무 설명을 안해줘
store.dispatch(increase());
store.dispatch(decrease());
store.dispatch(changeText("안녕하세요"));
store.dispatch(addToList({ id: 1, text: "와우" }));
window.store = store;
window.unsubscribe = unsubscribe;
이렇게 해놓고 콘솔에다가 store.dispatch({type: ‘INCREASE’})를 호출해보면 값이 추가되는 것을 볼 수 있다. 그 외에 나머지 DECREASE, CHANGE_TEXT, ADD_TO_LIST도 마찬가지로 테스트 해보자. 호출할때마다 디스패치 되는 것을 볼 수 있다.
그리고 콘솔에 unsubscribe를 호출해보자. 그러면 그 뒤로는 액션을 디스패치 해도 더이상 변화가 콘솔에 찍히지 않는 것을 볼 수 있다. 그리고 다시 store.getState()를 호출해보면 카운트는 올라가 있는 걸 확인할 수 있다. unsubscribe해도 콘솔에만 반영이 안된거지 count값은 올라가고 있었음을 확인할 수 있다.
우리가 앞으로 리액트에서 리덕스를 사용하게 될때는 이 subscribe라는 함수는 사용하지 않는다. getState도 미들웨어를 사용하기전까진 쓸일 없을 것이다. 그대신에 connect, useSelect, useStore, useDispatch등 헬퍼 훅들을 사용해 리액트와 리덕스를 연결하게 된다.
이제 리액트와 리덕스를 연동해보도록 하자.
Redux 모듈 만들기 (React와 Redux 연결하기)
리덕스 모듈이란 ‘액션타입, 액션생성함수, 리듀서’ 모두가 들어있는 것을 모듈이라고 부른다. 이 세가지는 각각 다른 파일로 저장할수도 있다. 하지만 한 파일에 몰아서 작성하자. 이것을 Ducks 패턴이라고 한다. 여기서 한가지 특징은 Reducer는 export default로 내보내고, Action Creator은 export function으로 내보낸다는 것이다. 아래 사진을 참고하자.
그리고 Ducks 패턴을 불러올때 import * as reducers from ‘./ducks/index’ 이런식으로 한번에 불러올 수도 있고, import { loadList, createList } from ‘./duks/index’ 이렇게 하나씩 불러올 수도 있다.
자 이제 src에 /module폴더를 만들고 그안에 counter.js를 만들어보자.
module/counter.js
// ACTION TYPE
const SET_DIFF = "counter/SET_DIFF"; //ducks 패턴으로 액션타입을 선언할때 이렇게 접두사로 모듈이름을 넣어주는데 그이유는 다른모듈과 이름이 중복되지 않게 하기 위함이다.
const INCREASE = "counter/INCREASE";
const DECREASE = "counter/DECREASE";
// ACTION CREATOR
export const setDiff = (diff) => ({ type: SET_DIFF, diff });
export const increase = () => ({ type: INCREASE });
export const decrease = () => ({ type: DECREASE });
// 초기상태 선언
const initialState = {
number: 0,
diff: 1, //더해줄 값
};
// REDUCER
export default function counter(state = initialState, action) {
switch (action.type) {
case SET_DIFF:
return {
...state,
diff: action.diff,
};
case INCREASE:
return {
...state,
number: state.number + state.diff,
};
case DECREASE:
return {
...state,
number: state.number - state.diff,
};
default:
return state;
}
}
이번엔 todos.js를 하나 더 만든다.
todos.js
// ACTION TYPE
const ADD_TODO = "todos/ADD_TODO";
const TOGGLE_TODO = "todos/TOGGLE_TODO";
// ACTION CREATOR
let nextID = 1;
export const addTodo = (text) => ({
type: ADD_TODO,
todo: {
id: nextID++,
text,
},
});
export const toggleTodo = (id) => ({
type: TOGGLE_TODO,
id,
});
//초기화
const initialState = {
/* 이렇게 받아올 것이다
{
id:1,
text:'예시',
done: false
}
*/
};
// REDUCER
export default function todos(state = initialState, action) {
switch (action.type) {
case ADD_TODO:
return state.concat(action.todo);
case TOGGLE_TODO:
return state.map((todo) =>
todo.id === action.id
? {
...todo,
done: !todo.done,
}
: todo
);
default:
return state;
}
}
그리고 이 두개의 모듈을 연결해줄 root파일을 만들어야 하는데 index.js라고 만들어보자.
module/index.js
import { combineReducers } from "redux";
import counter from "./counter";
import todos from "./todos";
const rootReducer = combineReducers({
counter,
todos,
});
export default rootReducer;
//두개의 모듈을 하나의 rootReducer로 만들어서 내보내줘야함.
//리액트에 리덕스를 붙이기 위해서는 react-redux 패키지를 설치해야함.
이제 리액트에 리덕스를 붙이기 위해서 react-redux를 설치한다.
yarn add react-redux
이제 src의 index.js에 우리가 만든 리덕스 모듈들을 붙여줘보자.
src/index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import { Provider } from "react-redux"; //리액트리덕스 붙여주기
import { createStore } from "redux"; //스토어 만들기위해 리덕스에서 불러오기
import rootReducer from "./module"; //우리가 만든 모듈 뭍여주기
const store = createStore(rootReducer); //store를 생성해준다.
console.log(store.getState()); //콘솔에 우리가 만든 카운트랑 투두스 모양이 있는지 확인해본다.
ReactDOM.render(
<React.StrictMode>
<Provider //Provider로 App을 감싸주고 그 안에 우리가 만든 store를 넣어주면 완성이다!
store={store}
>
<App />
</Provider>
</React.StrictMode>,
document.getElementById("root")
);
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
아 진짜 굳이 붙이는 방법도 이렇게 귀찮은데 리덕스를 써야되나 싶어진다 ㅋㅋㅋㅋㅋ….
이번 회사에서 진행하는 프로젝트 어떤걸로 쓸지 고민중인데 ㅜㅜ 프로젝트 크기가 어떨지 모르겠다.
더 커질수도 있고 아닐수도 있어서 리덕스를 쓸지말지 판단을 못내리는 중.
아무래도 미들웨어까지 배우고 결정해야할듯.. 추석까지는 다 끝내고 판단할 수 있게 해놔야지.
역시나 자세하고 정확한 내용은 벨로퍼트의 위키를 참고하도록 하자.
오늘은 여기까지..
시청 영상 35강 04~05까지
프론트엔드 개발 올인원 패키지 with React Online. 👉 https://bit.ly/31Cf1hp
Comments