리액트 프로젝트에 리덕스를 적용하기 위해서 리덕스 모듈을 만들어보자!
리덕스 모듈은 다음과 같은 항목들이 모두 들어있는 자바스크립트 파일이다.
1. 액션 타입
2. 액션 생성함수
3. 리듀서
위 항목들을 각각 다른 파일에 저장할 수도 있다.
리덕스 공식 GitHub 레퍼지토리에 등록되어있는 예제 프로젝트를 보면 아래와 같이 코드가 분리되어 있다.
- actions
- index.js
- reducers
- todos.js
- visibilityFilter.js
- index.js
구조를 보면 액션과 리듀서가 다른 파일에 정의되어 있는 것을 알 수 있다.
하지만, 코드들이 꼭 분리되어야 하는 것은 아니다. 코드들이 다른 디렉터리에, 다른 파일에 분리되어 있으면
개발할 때 꽤 불편할 수도 있다. 그래서 우리는 리듀서와 액션 관련 코드들을 하나의 파일에 몰아서 작성할 것이고 이런 패턴을 Ducks 패턴이라고 부른다.
Ducks 패턴: 기능중심으로 파일을 나누는 패턴을 말한다.
💡 액션 타입과 액션 생성자 함수, 리듀서 등을 하나의 파일에서 관리한다.
❗ 주의할 점
1. 리듀서 함수는 export default로 정의해야 한다.
2. 액션 함수는 export로 정의해야 한다.
3. 액션타입을 정의할 때 reducer/ACTION_TYPE 형태로 적어줘야 한다.
counter 모듈 만들기
기본적인 사항들을 모두 알았으니 counter 모듈을 만들어보자
src 디렉터리에 modules 디렉터리를 생성하고, 내부에 counter.js 파일을 생성하여 다음과 같이 코드를 작성한다.
modules/counter.js
먼저, 액션 타입을 미리 선언해주자
const SET_DIFF = 'counter/SET_DIFF';
const INCREASE = 'counter/INCREASE';
const DECREASE = 'counter/DECREASE';
💡 Ducks 패턴을 사용할 땐 액션의 이름에 접두사를 넣어줘 다른 모듈과 액션 이름이 중복되는 것을 방지할 수 있다.
액션 생성함수를 만들고 export 키워드를 사용해서 내보내준다.
여기서는 화살표 함수가 간편해서 화살표 함수를 사용했지만 일반 함수로 작성해도 상관없다.
export const setDiff = diff => ({ type: SET_DIFF, diff });
export const increase = () => ({ type: INCREASE });
export const decrease = () => ({ type: DECREASE });
다음으로 초기 상태를 선언해준다.
const initialState = {
number: 0,
diff: 1
};
이어서 리듀서 함수를 선언하고 export default 키워드를 사용해서 내보내준다.
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 모듈 만들기
내친김에 todos 모듈까지 만들어보자.
counter 모듈과 마찬가지로 modules 디렉터리에 todos.js 파일을 생성하고 다음과 같이 코드를 작성한다.
modules/todos.js
액션 타입 먼저 선언
const ADD_TODO = 'todos/ADD_TODO';
const TOGGLE_TODO = 'todos/TOGGLE_TODO';
액션 생성함수 선언
여기서 nextId는 todo 데이터에서 사용할 고유 id 변수이다.
let nextId = 1;
export const addTodo = text => ({
type: ADD_TODO,
todo: {
id: nextId++,
text
}
});
export const toggleTodo = id => ({
type: TOGGLE_TODO,
id
});
초기 상태 선언
const initialState = [];
리듀서 함수를 선언하고 export default 키워드를 사용해서 내보내준다.
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;
}
}
루트 리듀서 만들기
현재까지 counter와 todos 모듈 두개를 만들었다. 하지만 한 프로젝트에서 리듀서를 여러개 사용하려면 하나로 합쳐서 사용해야 한다. 이렇게 하나로 합친 리듀서를 루트 리듀서라고 부르며 리듀서들은 리덕스에 내장되어 있는 combineReducers 함수를 사용해서 합칠 수 있다.
modules 디렉터리에 index.js를 만들고 다음과 같이 코드를 작성해보자
modules/index.js
import { combineReducers } from "redux";
import counter from './counter';
import todos from './todos';
const rootReducer = combineReducers({
counter,
todos
});
export default rootReducers;
이렇게 하면 counter 모듈과 todos 모듈이 합쳐지게 된다!!
리덕스 스토어를 만드는 작업은 src 디렉터리의 index.js에서 진행한다.
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {createStore} from 'redux';
import rootReducer from './modules';
const store = createStore(rootReducer);
console.log(store.getState());
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
브라우저에서 코드를 실행하고 콘솔문을 확인해보면 state가 정상적으로 출력되는 것을 알 수 있다
리액트 프로젝트에 리덕스 적용하기
먼저, 터미널에 다음과 같은 명령어를 입력해 react-redux 라이브러리를 설치한다.
$ yarn add react-redux
이후에 index.js에 Provider 컴포넌트를 불러와 App 컴포넌트를 감싸준다.
그리고 Provider의 props에 store를 넣어준다.
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {createStore} from 'redux';
import { Provider } from 'react-redux';
import rootReducer from './modules';
const store = createStore(rootReducer);
ReactDOM.render(
<Provider stpre={store}>
<App />
</Provider>,
document.getElementById('root')
);
reportWebVitals();
여기까지 진행했다면 리덕스를 사용하기 위한 모든 준비가 끝났다.
참고
벨로퍼트와 함께하는 모던 리액트 https://react.vlpt.us/redux/04-make-modules.html
'Redux' 카테고리의 다른 글
[Redux] 6. 리덕스로 투두 리스트(TodoList) 구현하기 (0) | 2021.06.29 |
---|---|
[Redux] 5. 리덕스 개발자도구 적용하는 방법 (0) | 2021.06.29 |
[Redux] 4. 리덕스로 카운터 구현하기 (0) | 2021.06.29 |
[Redux] 2. 리덕스 설치 및 예제 실행 (0) | 2021.06.28 |
[Redux] 1. 리덕스의 정의 및 특징 (0) | 2021.06.28 |