본문 바로가기
React

Redux 세 가지 원칙

by ttum 2020. 2. 18.

1. Single source of truth

The state of your whole application is stored in an object tree within a single store.

어플리케이션 내의 state는 단일한 store안에 있는 객체 트리에 저장된다.

 

- 서버에서 가져온 state를 클라이언트쪽에 나열하거나 흡수시킬때 별다른 추가적인 코딩 없이 쉽게 쓸 수있다.

- 디버깅이 쉬워진다.

- 개발 사이클이 더 빨라진다. (undo/redo 등의 조금 어려웠던 작업들이 간단하게 해결가능해진다.)

 

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
    }
  ]
}
*/

 

2. State is read-only

The only way to change the state is to emit an action, an object describing what happened.

state를 변화시키는 유일한 방법은 무슨 일이 일어나야하는지 기술하는 action 객체를 내보내는 것이다.

 

- view나 network callback은 절대로 state를 직접적으로 바꿀 수 없다. 대신 바꾸겠다는 의도 정도만 표현한다.

- 모든 변화들은 중앙화(centralized)되어 있고 순차적으로 이루어지기에 조금의 race condition도 발생하지 않는다.

- action은 일반적인 객체이므로 log로 찍거나, 나열, 저장, 디버깅 용도로도 사용될 수 있다.

* race condition: 둘 이상의 입력 또는 조작의 타이밍이나 순서등이 결과값에 영향을 줄 수 있는 상황.

 

store.dispatch({
  type: 'COMPLETE_TODO',
  index: 1
})
store.dispatch({
  type: 'SET_VISIBILITY_FILTER',
  filter: 'SHOW_COMPLETED'
})

 

3. Changes are made with pure functions

To specify how the state tree is transformed by actions, you write pure reducers.

 

- Reducer는 이전의 state나 action을 가지고와서 다음 state를 리턴하는 pure function이다.

- 이전의 state를 변형한 것 대신 새로운 state 객체를 리턴해야한다는 것을 꼭 기억하자.

- 하나의 reducer로 시작하여, 앱이 점차 커져감에 따라 더 작은 reducer들로 쪼개면 된다.

- reducer도 단지 함수이기에 호출 순서를 바꾼다던가 추가적인 데이터를 보낸다거나 페이징과 같이 재사용이 가능한 reducer들을 만들 수 있다.

 

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)

 

Referecne

https://redux.js.org/introduction/three-principles/