action
// 액션 타입
const ADD_TODO = 'Add_todo'
// 액션 생성자
function addToDo(_todo) {
return ({
type: ADD_TODO,
todo: _todo // store에 있는 state
})
}
- type 속성과 payload 속성을 포함하고 있는 객체
- store 안에 있는 state들을 변경하기 위해 action을 store에 전달한다.
- 액션 객체 자체를 리터럴 방식으로 생성하기 보단, 액션 객체를 반환하는 함수(=액션 생성자)를 만드는 것이 좋다.
- 액션 생성자는 payload를 인자로 받는다.
- 액션의 타입을 적을 때 실수할 여지를 없애기 위해서 액션의 타입을 상수로 만든다.
reducer
// state의 초기값
const initalState = {
count: 0
}
function reducer(state = initalState, action) {
// action 1
if(action.type === 'PLUS')
return { count: state.count + 1 } // 새로운 객체 반환
// action 2
if(action.type === 'MINUS')
return { count: state.count - 1 } // 새로운 객체 반환
return state // 기존 객체
}
// combineReducer
import { combineReducers } from 'redux'
const rootReducer = **combineReducers**({
tomato: tomatoReducer,
potato: potatoReducer
})
// 리듀서를 여러개로 합쳤다면, useSelector의 사용법이 달라진다.
const title = useSelector(state => state.**postReducer**.title) // 어떤 리듀서인지 명시해야함
- 스토어 내부에서 액션을 전달받아서 state 값을 변경시킨다.
- 액션 각각에 대한 로직이 reducer 함수 내부에 if 문 또는 switch 문으로 구별되어 있다.
- redo, undo 와 같은 작업을 위해서 기존의 state 객체를 변경하면 안된다. 기존의 state 객체를 활용해서 새로운 state 객체를 만들고 그 새로운 객체를 반환해야 한다. (기존 state immutable)
- state 가 복잡해짐에 따라 하나의 reducer를 여러 개의 reducer로 나누고, 각 reducer 들은 자기가 관리하는 state를 가지고 있다.
- 여러 개로 나뉘어진 reducer는 combineReducers 를 통해 하나의 reducer로 합친다.
store
// store 객체 생성
import { createStore } from 'redux'
const store = createStore(myReducer) // store와 reducer를 연결
// state 객체 불러오기
store.getState()
// 액션을 store의 reducer에게 전달
store.dispatch(액션 생성자 함수())
// state 변경 주시하고 있기
const unsubscribe = store.subscribe(콜백 함수)
// unsubscribe 호출
unsubscribe()
- dispatch : store에 연결되어 있는 reducer에게 액션 객체를 전달하는 함수이다.