상태관리가 필요한 이유를 이해하기 위해선 우선 상태가 무엇인지 알아야한다
상태란?
상태(state)는 React에서 컴포넌트 내에 관리되는 변수, 즉 변하는 데이터들이다.
React API setState()로 선언되는 그것 맞다.
컴포넌트들은 서로 상태를 공유해야한다. 컴포넌트들은 props 형태로 상태를 공유한다.
자식 컴포넌트간에는 상태 공유가 불가능하고, 부모 컴포넌트를 통해서만 상태를 공유할 수 있다. 이때 문제는, 컴포넌트 계층이 많아지면 props 하나를 전달하는데 거쳐야하는 컴포넌트가 많아지고, 중간단계의 컴포넌트들은 사용하지도 않는 props를 들고있어야하는 문제가 생긴다.
이러한 문제를 props drilling
이라고 부르는데, 프로젝트가 커질수록 state 관리가 어려워진다.
💡 이래서 전역적으로 상태를 관리하는 상태관리 라이브러리가 필요하다 !
스토어의 상태를 변경하는 용도로 사용된다.
직접 상태를 변경하지는 않고 어떤 상태로 변경할 것인지 결정하는 역할만 한다.
state값을 변경해준다.
리듀서를 호출하는데 그때, 현재의 state값과 action, 총 2개의 인자 값을 전달한다.
state를 정의하고 전달 받은 액션에 따라 스토어의 상태 변경이 이루어진다.
실제 스토어의 상태 변경은 리듀서에서 이루어진다.
액션과 리듀서의 연결 지점이다.
또한 모든 것을 총괄하는 지점이다.
Redux는 단일 스토어 하나만을 갖는다.
버튼 클릭에 따라, backgroundColor가 변경되는 간단한 어플리케이션을 Redux로 만든다고 생각해보자.
Redux.createStore(reducer);
function reducer(state, action){ //인자 2개 받고,
if(state === undefined){ //state가 undefined라는건 초기값이라는 것!
return {color: 'yellow'} //retur된 초기 state값
const state = store.getState();
onClick=
"store.dispatch({type:"ChHANGE_COLOR", color: "red"})"
// type은 필숫값이며 그 다음에 변경해주고 싶은 state 값을 적어준다.
//{}객체자체가 reducer함수의 action인자로 받아지게 된다!
function reducer (state, action) {
if(state === undefined){
return{color:"yellow"}
}
const newState;
if (action.type === "CHANGE_COLOR"){
newState = Object.assign({}, state, {color: action.color}); // {}빈 객체에, state를 복사해서 {color: action.color}를 넣어줘! 라는 뜻.
}
return newState;
{color: "red"} 가 들어있는 것을 알 수 있다.
(onClick한 아이가 가지고 있는 객체에 따라 color는 변경될 것이다.)
store.subscribe(red);
리덕스에는 미들웨어(Middleware)
라는 개념이 존재한다. 리덕스의 미들웨어를 사용하면 액션 객체가 리듀서에서 처리되기 전에 우리가 원하는 작업들을 수행 할 수 있다. 예를 들어 특정 조건에 따라 액션이 무시되게 만들 수 있다.
미들웨어는 주로 비동기 작업을 처리할 때 많이 사용된다.
Context API를 사용해서 글로벌 상태를 관리할 때에는 일반적으로 기능별로 Context를 만들어서 사용하는 것이 일반적이다. 반면 리덕스에서는 모든 글로벌 상태를 하나의 커다란 상태 객체에 넣어서 사용하는 것이 필수이다. 때문에 매번 Context를 새로 만드는 수고로움을 덜 수 있다.