많은 상태를 자바스크립트 코드로 관리해야 한다. 그러나 항상 변하는 상태를 관리하기란 어렵다. 상태가 복잡해지면 상태가 언제, 왜, 어떻게 업데이트 할지 제어할 수 없다. 더하여 프론트엔드 제품 개발에 있어서 Optimistic update, 서버렌더링, 라우트가 일어나기 전에 데이터 가져오기 등 고려해야 할 요소가 늘어나고 있다. Redux는 상태 변화가 일어나는 시점에 제약을 두어 상태 변화를 예측 가능하게 만들고자 한다.
{
type: 'TOGGLE_VALUE'
}
액션 객체는 다음과 같은 형식으로 이루어짐. 액션 객체는 type필드를 반드시 가지고 있어햐 한다. 이 값을 액션의 이름이라고 생각하면 된다. 그리고 그 외의 값들은 나중에 상태 업데이트르 할 때 참고해야 할 값이며, 작성자 마음대로 넣을 수 있다.
function addTodo(data){
return{
type:'ADD_TODO',
data
};
}
어떤 변화를 일으켜야 할 때마다 액션 객체를 만들어야 하는데 이를 함수로 만들어서 관리
리듀서
리듀서는 변화를 일으키는 함수이다. 액션을 만들어서 발생시키면 리듀서가 현재 상태와 전달받은 액션 객체를 파라미터로 받아온다. 그리고 두 값을 참고하여 새로운 상태를 만들어서 반환해 준다.
스토어
한 개의 프로젝트는 한개의 스토어만 가질 수 있다. 스토어 안에는 현재 애플리케이션 상태와 리듀서가 들어가 있으며, 그 외에도 몇 가지 중요한 내장 함수를 지닌다.
디스패치
디스패치는 스토어의 내장 함수 중 하나이다. 디스패치는 액션을 발생시키는 것이라고 이해하면 된다. 이 함수는 dispatch(action)과 같은 형태로 액션 객체를 파라미터로 넣어서 호출한다. 이 함수가 호출되면 스토어는 리듀서 함수를 실행시켜서 새로운 상태를 만들어준다.
구독
구독도 스토어의 내장 함수 중 하나이다. subscribe 함수 안에 리스너 함수를 파라미터로 넣어서 호출해 주면, 이 리스너 함수가 액션이 디스패치되어 상태가 업데이트될 때마다 호출된다.
전체 과정: dispatch(action) -> 리듀서 실행, 새로운 상태 만들어서 반환 -> subscribe 함수 안의 리스너 함수 호출
console.log(store.getState())
/* Prints
{
visibilityFilter: 'SHOW_ALL',
todos: [
{
text: 'Consider using Redux',
completed: true,
},
{
text: 'Keep all state in a single tree',
completed: false
}
]
}
*/
store.dispatch({
type: 'COMPLETE_TODO',
index: 1
})
store.dispatch({
type: 'SET_VISIBILITY_FILTER',
filter: 'SHOW_COMPLETED'
})
function visibilityFilter(state = 'SHOW_ALL', action) {
switch (action.type) {
case 'SET_VISIBILITY_FILTER':
return action.filter
default:
return state
}
}
function todos(state = [], action) {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{
text: action.text,
completed: false
}
]
case 'COMPLETE_TODO':
return state.map((todo, index) => {
if (index === action.index) {
return Object.assign({}, todo, {
completed: true
})
}
return todo
})
default:
return state
}
}
import { combineReducers, createStore } from 'redux'
const reducer = combineReducers({ visibilityFilter, todos })
const store = createStore(reducer)