React에서 꼭 마주하게 되는 것 중 하나가 상태관리 라이브러리입니다.
Redux는 가장 많이 사용되는 상태관리 라이브러리입니다. React에서 만드는 컴포넌트들의 상태 관련 로직들을 여러 파일로 분리해서 관리 할 수 있습니다. 부모 컴포넌트와 자식 컴포넌트나 컴포넌트끼리 상태를 공유할 때 *Prop Drilling같이 여러 컴포넌트를 거치지 않고 여기저기 흩어져있는 상태 값을 전달할 수 있습니다.
추가로 Redux Middleware를 통해 비동기 작업, logger등 추가 기능을 사용할 수 있습니다.
React에서 최근 가장 많이 사용되는 라이브러리 Redux, Mobx, Recoil 등이 있습니다.
https://openbase.com/categories/js/best-react-state-management-libraries
Prop Drilling
React의 데이터 흐름은 단방향 데이터 흐름(one-way data flow)입니다. 부모 컴포넌트로부터 자식 컴포넌트가 props를 전달받는 것이죠. 본인의 프로젝트에서 단순히 prop-drilling을 피하거나 단순 값을 전달할 때엔 React에서 제공하는 useState와 Context API로도 충분합니다.
Context API : https://ko.reactjs.org/docs/context.html
상태 값을 전달하기 위해 부모 -> 자식으로 props를 내려줍니다. 한두 번 정도야 상관없지만, depth가 깊어지면서 자식 컴포넌트가 10개였다면 부모-자식-자식-... 사용하려는 child까지 전달해줘야 사용할 수 있습니다. 이것이 Prop-Drilling입니다. Redux는 이뿐 아니라 컴포넌트 개수, 공유하는 state들이 많아진다면 state가 어디서 어떻게 변하는지, re-rendering가 어떤 컴포넌트에서 발생했는지 파악하기가 힘들어 사용하는 것이죠.
상태에 어떠한 변화가 필요할 때, 액션을 발생시킵니다. Event가 실행되면 객체를 정의해 type을 지정해줍니다. 예를들어 button을 눌러 1씩 증가하는 type
{
type: 'increment'
}
액션 객체를 만드는 함수입니다.
function login(data) {
return {
type: 'LOGIN_REQUEST',
data,
}
}
// parameter를 받아서도 가능
const addPost = (content) => {
type: 'ADD_POST',
content,
}
reducer는 실질적으로 액션이 발생했을때 state의 변화를 일으키는 함수입니다. 2개의 parameter를 받아옵니다.
const reducer = (state, action) => {
//상태 업데이틀 로직, 불변성을 지켜야합니다.
return nextState;
}
Redux에서 하나의 애플리케이션에는 하나의 Store를 만듭니다.
Store안에는 초기의 state, Reducer, 몇가지 내장 함수들이 있습니다.
dispatch는 스토어의 내장 함수 중 하나입니다. dispatch는 액션을 발생시킨다고 생각하시면 됩니다. dispatch 함수에는 action을 parameter로 받아옵니다.
// 위 예제들의 type들 increment, LOGIN_REQUEST
dispatch({
type: 'increment'
})
dispatch({
type: 'LOGIN_REQUEST'
})
이미지 출처) 생활코딩 Redux강의 redux 흐름