여러 개의 상태관리와 유지보수를 쉽게하고 컴포넌트 별로 세분화하는 코드를 작성하기위해 리듀서도 세분화할 필요가 있다. 관리해야 할 상태과 적을 때는 상관없지만 관리해야 할 상태의 수가 많아질수록 액션과 리듀서를 나눴을 때 위와 같은 장점이 있을 것이다.
"+" 버튼을 눌렀을 때 숫자를 증가시키는 컴포넌트(Count)와 문자를 추가하는 컴포넌트(Text)를 생성하였다. 또한 이에 대한 액션과 리듀서를 분리하였다.
reducer 만들기
먼저 src/reducers 라는 폴더를 만들고 각각 Count, Text에 대한 리듀서를 생성한다. 각각 해당하는 컴포넌트에 대한 리듀서 역할을 한다.
// ./src/reducers/count.js
import { ADD_COUNT } from "../actions/count"
const INIT_STATE = {
count : 0,
}
export const countReducer = (state=INIT_STATE, action) => {
switch(action.type) {
case ADD_COUNT:
return {
...state,
count : action.count
}
default:
return state
}
}
// ./src/reducers/text.js
import { ADD_WORD } from "../actions/text"
const INIT_STATE = {
word: ''
}
export const textReducer = (state=INIT_STATE, action) => {
switch(action.type) {
case ADD_WORD:
return {
...state,
word : state.word.concat(action.word)
}
default:
return state
}
}
action 만들기
이제 dispatch를 실행할 액션을 컴포넌트 별로 만들어준다.
// ./src/actions/count.js
export const ADD_COUNT = 'ADD_COUNT';
export const addCount = (count) => {
return {
type: ADD_COUNT,
count: count + 1
}
}
// ./src/actions/text.js
export const ADD_WORD = 'ADD_WORD';
export const addWord = (word) => {
return {
type: ADD_WORD,
word
}
}
store 만들기
이제 store를 생성하도록 한다. 이를 위해 분리된 reducer를 하나로 합쳐야 하며 "combineReducers"를 사용할 수 있다.
두 개의 reducer를 불러와 묶어주며 이를 createStore에 전달하여 store를 생성한다.
// ./src/store/index.js
import { createStore, combineReducers } from 'redux';
import { textReducer } from '../reducers/text';
import { countReducer } from '../reducers/count';
const rootReducer = combineReducers({
textReducer,
countReducer
})
const store = createStore(rootReducer)
export default store
이후 index.js를 통해 App과 store를 연결하여 각각의 컴포넌트에서 상태와 액션에 쉽게 접근할 수 있도록한다.
// ./index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { Provider } from 'react-redux';
import store from './store/index';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
컴포넌트에서 상태와 액션 가져오기
각각의 컴포넌트에서 상태와 액션을 가져오기 위해서 "react-redux"에서 제공하는 connect를 사용할 수 있다.
connect는 특정 함수에서 반환하는 상태와 액션을 컴포넌트에 전달하는 역할을 한다. connect의 인자에는 순서대로 상태와 액션에 관련된 함수를 전달하며, 상태에 대한 함수를 사용하지 않는다면 첫 번째 인자에 null을 전달한다.
mapStateToProps에서는 상태를 반환해준다. state를 통해 각각의 reducer를 통해 상태에 접근할 수 있다.
// ./components/Count.jsx
import React from 'react';
import { connect } from 'react-redux';
import { addCount } from '../actions/count';
function Count({count, addCount}) {
function onClick() {
addCount(count)
}
return (
<div className="count">
<h2>count: {count}</h2>
<button onClick={onClick}>+</button>
</div>
)
}
function mapStateToProps(state) {
return {
count: state.countReducer.count
}
}
function mapDispatchToProps(dispatch) {
return {
addCount: (count) => dispatch(addCount(count))
}
}
export default connect(mapStateToProps, mapDispatchToProps) (Count)
'React' 카테고리의 다른 글
[React] JSX (0) | 2021.11.16 |
---|---|
[React] Custom Hook (0) | 2021.10.10 |
[React] PropTypes 사용하기 (0) | 2021.09.21 |
[React] 디자인 패턴 : Container - Presenter 패턴 (0) | 2021.07.31 |
[React] Life Cycle (0) | 2021.07.23 |