리덕스는 리액트에서 가장 많이 사용되는 자바스크립트 상태(state)관리 라이브러리의 한 종류이다.
컴포넌트간의 복잡한 state 관리를 쉽게 하기위해서 Store 에서 전역으로 state 를 관리할 수 있게끔 도와주는 도구이다..!
"Single source of truth", Store 는 단 하나이며, 모든 앱의 상태는 이곳에 보관됨. 스토어를 여러개 생성할 수는 있으나, 원칙에 위반된다.
"Immutability", 상태는 오로지 읽을 수만 있다. 변경하려면 모든 상태가 변경되어야 함.
리액트에서 setState 를 사용할때 state 배열에 직접 push 를 한다던가 상태 자체의 값을 바꾸지 않고Object.assign
등을 사용해서 복사된 객체를 사용해서 업데이트를 하듯 리덕스(redux) 에서도 기존의 상태를 건들지 않고 새로운 상태를 생성해서 업데이트를 해야 한다.
"Pure function", 상태의 변경은 어떠한 사이드 이펙트도 만들지 않아야 함.
- 리듀서 함수는 이전 상태와, 액션 객체를 파라미터로 받습니다.
- 이전의 상태는 절대로 건들이지 않고, 변화를 일으킨 새로운 상태 객체를 만들어서 반환합니다.
- 똑같은 파라미터로 호출된 리듀서 함수는 언제나 똑같은 결과값을 반환해야만 합니다.
위의 gif 들을 보면서 각각의 기능에 대해서 알아보자
type
, payload
를 포함하는 JavaScript 객체type
에는 reducer
에 전달될 action
의 type
을 나타내며 payload
에는 데이터를 담는다.const action1 = {
type: 'namespace/getMyData',
payload : {
id: 123
}
}
action
을 생성할 필요없이 함수 내에서 action
을 생성해서 사용하는 방법const addObj = (id) => ({
// 함수내에서 action 이 필요로하는 type, data 를 생성함
type: 'namespace/getMyData',
payload : {
id: String(id).slice(1)
}
})
action
에 따라 reducer
에서는 새로운 상태를 만들어낸다. Store
는 그 상태를 저장하는 곳const store = createStore(reducer, initialState);
action.type
에 따라서 동일한 결과를 리턴해야하는데 new Date() , axios.get() 등등 이것들은 리듀서 함수 밖에서(리듀서 함수에 들어오기 전, 미들웨어 등) 처리해야 함.const reducer = (state, action) => {
switch(action.type) {
case 'namespace/getMyData':
const obj = { id: action.payload.id }
return { ...state, obj }
default:
return state
}
}
const store = createStore(reducer, initialState);
Action
을 redux
로 보내는 함수dispatch
후에 action
은 middleware
를 거쳐 reducer
에 도달function MyApp(){
const dispatch = useDispatch()
return (
<button
onClick = {() => {
dispatch(addObj(1234));
}}
>Submit</button>
)
}