동기
- 항상 변할 수 있는 상태를 업데이트하는 위치와 주체가 다르기때문에
- ->상태를 언제, 왜 어떻게 업데이트 할지 제어하기위해
- react 에서는 뷰레이어에서 비동기와 DOM 조작을 없애버렸음
- → react에서는 데이터를 관리하는일에 관여하지 않음
- redux는 상태변화가 일어나는 시점에 제약을 두어 상태 변화를 예측 가능도록함
- react의 context API 에서 useReducer를 사용하면 유사함
- 다만, useReducer 가 존재하기도 전에 만들어져서 글로벌 상태관리로 많이 사용됨
redux vs context API
- 미들웨어
- redux에만 존재함
- 미들웨어를 사용하여 action 객체가 reducer에게 처리되기 전에 특정 작업 수행 가능
- ex) 특정 조건에 따라 action 무시, action 출력, 서버 로깅 등등
- 주로 비동기 작업을 처리할 때 많이 사용됨
- 유용한 함수와 hooks
- 하나의 커다란 상태
- 매번 context를 새로 만드는 수고로움을 덜 수 있음
3원칙
- app 의 모든 상태는 하나의 store 안에 하나의 객체 트리 구조로 저장됨
- 상태를 변화시키는 유일한 벙법
- → 무슨일이 벌어지는지를 묘사하는 action 객체를 전달하는 것 뿐
- action 에 의해 상태 트리가 어떻게 변화 하는지를 지정하기 위해 프로그래머는 순수 reducer를 작성해야함
- reducer는 이전 상태와 action 을 받아 다음 상태를 반환하는 순수함수
- 새로운 상태객체를 생성해서 반환해야함
- reducer는 함수 이기때문에 호출되는 순서를 정하거나 추가적인 데이터를 넘길 수도 있음
- 재사용 가능한 reducer도 작성 가능
용어
상태
- 상태 트리 라고도함
- store에 의해 관리되고 getState()에 의해 반환되는 하나의 상태값을 지칭함
- redux app 전체 상태를 나타내며, 보통 깊게 중첩된 객체임
action
- 상태를 변화시키려는 의도를 표현하는 일반 객체
- 모든 데이터는 action으로써 보내짐
- type 필드
- 상수로 정의
- 다른 모듈에서 임포트 가능
- symbol 보다는 문자열을 권장
- type 이외는 마음대로 필드 추가해도됨
{
type: "ADD_TODO",
data: {
id: 0,
text: "리덕스 배우기"
}
}
action creator(선택)
- 액션을 만드는 함수
- 단순히 받아서 action 객체로 리턴
- component에서 쉽게 action을 발생시키기 위함
export function addTodo(data) {
return {
type: "ADD_TODO",
data
};
}
// 화살표 함수로도 만들 수 있습니다.
export const changeInput = text => ({
type: "CHANGE_INPUT",
text
});
reducer
- API 호출을 reducer 안에 넣지 마세요
- state 초기값을 주지않으면 error
- 누적값과 값을 받아서 새로운 누적값을 반환하는 함수
- 누적값은 state이고, 누적될 값은 action
- 같은 입력이 있으면 같은 출력을 반환하는 순수함수여야만 함
- 사실상 createStore 시 reducer만으로 redux는 store, action 을 모두 세팅하는것으로 보임
function counter(state, action) {
switch (action.type) {
case 'INCREASE':
return state + 1;
case 'DECREASE':
return state - 1;
default:
return state;
}
}
dispatch function
- action을 발생시키는 store 내장 함수
- 호출시 store는 reducer를 실행시켜 해당 action을 처리
- action이나 비동기 action을 받음
- 하나나 여러개의 action을 store에 보낼수도 보내지 않을 수도 있음
redux module
아래 항목들이 모두 들어있는 자바스크립트 파일
- action type
- action creator
- reducer
- reducer와 action 을 서로 다른 파일에 분리 가능
- 하나의 파일에 작성하는것이 Ducks 패턴
root reducer
한 프로젝트에 여러개의 reducer가 있는경우 한 reducer로 합침
import { combineReducers } from 'redux'
import counter from './counter'
import todos from './todos'
const rootReducer = combineReducers({
counter,
todos
})
export default rootReducer
hook
useSelector
redux store의 상태를 조회하는 hook
const { number, diff } = useSelector(state => ({
number: state.counter.number,
diff: state.counter.diff
}));
- state의 값은 store.getState() 함수를 호출했을때 나타나는 결과물과 동일함
useDispatch
redux store의 dispatch를 함수에서 사용할 수 있게 해주는 hook
const dispatch = useDispatch();
// 각 액션들을 디스패치하는 함수들을 만드세요
const onIncrease = () => dispatch(increase());
const onDecrease = () => dispatch(decrease());
const onSetDiff = diff => dispatch(setDiff(diff));
참고자료
'Front-end > React' 카테고리의 다른 글
Styled-component (0) | 2022.12.05 |
---|---|
React Query (0) | 2022.11.28 |
Hook (0) | 2022.11.23 |
Next.js (0) | 2022.11.23 |
React core (0) | 2022.11.23 |