Redux가 좋은 이유!
리덕스는 component와 state를 분리하여 전역에서 상태관리가 가능하도록 만들어주는 라이브러리이다(react가 아니어도 사용가능).
여기에서 발생하는 이점은?
- 컴포넌트 간의 복잡한 데이터 흐름을 따라갈 필요가 없어진다.
- 단순히 props 전달을 위한 props driling을 제거해준다.
- 따라서 불필요한 리렌더링도 제거해준다.
- State 관리가 용이해진다.
- 개별 컴포넌트가 state를 변경하면 버그가 생겼을 때 추적이 어렵다.
- Redux에서 개별 컴포넌트는 state를 직접 수정하지 못하고 수정요청만한다.
- 따라서 state에 예상치 못한 변경이 발생했을때, state의 변경을 관리하는 store만 디버깅하여 문제를 찾아낼 수 있다.
store는 오직 저장소의 역할만 한다. (상태를 관리함)
// 스토어 생성하기
import { createStore } from 'redux';
const store = createStore(rootReducer);
Reducer는 Dispatch에게서 전달받은 Action 객체의 type값에 따라서 상태를 변경시키는 함수이다.
// 첫번째 인자에는 기존 state, default value를 설정해줘야함
// 그렇지 않을 경우 undefined가 할당되기 때문에 오류 발생함
// 두번째 인자에는 action 객체
const counterReducer = (state = count, action) => {}
type은 필수로 지정해야한다. (대문자와 Snake Case로 작성)// payload가 필요 없는 경우
{ type: 'INCREASE' }
// payload가 필요한 경우
{ type: 'SET_NUMBER', payload: 5 }
//--- 함수로 action 객체를 만드는 경우
// payload가 필요 없는 경우
const increase = () => {
return {
type: 'INCREASE'
}
}
// payload가 필요한 경우
const setNumber = (num) => {
return {
type: 'SET_NUMBER',
payload: num
}
}
useDispatch()는 Action 객체를 Reducer로 전달해 주는 Dispatch 함수를 반환한다.import { useDispatch } from 'react-redux'
const dispatch = useDispatch()
dispatch( increase() )
console.log(counter) // 2
dispatch( setNumber(5) )
console.log(counter) // 5
useSelector()는 컴포넌트와 state를 연결하여 Redux의 state에 접근할 수 있게 해주는 메서드임
// Redux Hooks 메서드는 'redux'가 아니라 'react-redux'에서 불러온다.
import { useSelector } from 'react-redux'
const counter = useSelector(state => state)
console.log(counter) // 1
1. Single source of truth
동일한 데이터는 항상 같은 곳에서 가지고 와야 한다는 의미. 즉, Redux에는 데이터를 저장하는 Store라는 단 하나뿐인 공간이 있음과 연결이 되는 원칙이다.
2. State is read-only
상태는 읽기 전용이라는 뜻으로, React에서 상태갱신함수로만 상태를 변경할 수 있었던 것처럼, Redux의 상태도 직접 변경할 수 없음을 의미합니다. 즉, Action 객체가 있어야만 상태를 변경할 수 있음과 연결되는 원칙이다.
3. Changes are made with pure functions
변경은 순수함수로만 가능하다는 뜻으로, 상태가 엉뚱한 값으로 변경되는 일이 없도록 순수함수로 작성되어야하는 Reducer와 연결되는 원칙이다.