MVC 모델의 복잡성을 개선하기 위해 나온 단방향 데이터 흐름을 적용한 "Flux"모델
2015년 React + Flux의 구조에 ‘Reducer’를 결합한 전역상태관리 라이브러리 ‘Redux’가 등장하게 된다.
Redux = (Red)ucer + Fl(ux)
리덕스를 통해 멀리 떨어져 있는 컴포넌트를 연결 할 수도 있고, 프로젝트 전체에서 참조해야하는 상태값 등에 바로 접근할 수 있다.
애플리케이션의 모든 상태는 하나의 스토어 안에 하나의 객체 트리 구조로 저장된다. 모든 변경 사항의 Store에 기록되기 때문에 데이터 흐름의 원천은 항상 ‘Store’이어야 한다.
상태를 변화시키는 유일한 방법은 무슨 일이 벌어지는 지를 묘사하는 액션 객체와 함께 dispatch 를 호출하는 방법 뿐(like dispatch)
액션에 의해 상태 트리가 어떻게 변화하는 지를 지정하기 위해 프로그래머는 순수 리듀서를 작성해야합니다.
리듀서는 이전 상탯값과 액션 객체를 입력으로 받아 새로운 상탯값을 만드는 순수 함수입니다.
:fetch 등의 비동기 로직, new Date(), Math.random()은 같은 input에 다른 return ⇒ 유닛 테스트 불가. 테스트 코드 작성에 용이합니다.
export const addCart = (item) => { // 액션 "생성 함수"
return {
type: "ADD_ITEM", // 액션 "객체"
payload: item,
};
};
const dispatch = useDispatch()
const [store, dispatch] = useState() // 여기서 state는 store
<FooComponent store={store} dispatch={dispatch} /> // 여기서 FooComponent는 내가 컨트롤하는 컴포넌트
(state, action) => nextState // state(혹은 store)와 action 객체를 받고 다음 state 리턴
// cartReducers.js
function cartReducer(state = INITIAL_STATE, action) {
switch (action.type) {
case "ADD_ITEM":
return [...state, action.payload]; // 스토어의 이전 상태에 새로운 item을 추가
case "DELETE_ITEM":
return [...action.payload]
default:
return state; // 해당 사항 없으면 이전 상태를 그대로 리턴
}
}
// store/reducer/index.js
import { combineReducers } from "redux";
import cartReducer from "./cartReducer";
export default combineReducers({ cartReducer });
import React from "react";
import ReactDOM from "react-dom";
import Routes from "./Routes";
import { Provider } from "react-redux";
import { createStore } from "redux";
import rootReducer from "./store/reducers";
const store = createStore(rootReducer);
ReactDOM.render(
<Provider store={store}>
<Routes />
</Provider>,
document.getElementById("root")
);