Redux 란 ?
리덕스는 자바스크립트 앱을 위한 예측 가능한 상태 컨테이너를 말합니다.
리덕스의 아키텍처를 통해 변경사항을 기록하고, "시간여행형 디버깅"을 사용하고, 완전한 에러 리포트를 서버로 보낼 수 있습니다.
*Flux 아키텍처를 더 편리하게 만드는 '전역 상태관리' 라이브러리로서 컴포넌트끼리 데이터 및 state 관리를 쉽고 효율적으로 할 수 있게 만듭니다.
Flux의 단방향 구조에서 전역 상태관리를 유연하게 하기 위한 상태관리 라이브러리입니다.
*Flux 란,
아래와 같이 단방향으로 흐르는 구조로 구성되어 있습니다.
어떠한 Action이 발생하였을 때 Dispatcher가 Action을 관리하고 Dispatcher의 통제하에 Store에 있는 데이터를 가져오거나 수정할 수 있습니다. 그리고 store에 저장된 데이터를 View에 나타내는 구조입니다
데이터의 흐름이 단방향이기때문에, View는 Dispatcher에 Action을 보낼 수 있고 역시 Dispatcher는 동일하게 Action을 Store의 수정을 통해 View에 반영합니다.
이러한 간단한 정의만으로는 Redux에 대해 이해하기가 쉽지 않습니다.
다른 것들을 배울 때와 마찬가지로 리덕스 또한 필요성을 느낄 때 배우게 되면 더 빨리 이해하게 됩니다.
React 로 코드를 치면서 state, props 등의 상태관리 하는데에 데이터 흐름의 구조가 복잡해져 관리의 어려움을 느꼈습니다.
그때는 Redux에 대해 알기 전이라 '원래 이렇게 하는건가?', '나만 어려운가?' 하는 생각을 했던 것 같습니다.
그렇게 필요성을 느끼고 난 뒤 Redux의 사용도를 알게되니 더 배우고 싶고 써먹고 싶어졌습니다.
Redux 의 필요성
데이터의 흐름이 직접적인 연결로 자식에서 부모로 부모에서 자식으로 여러번 얽히다 보면 복잡도 상승 !
복잡도가 높아지면서 성능도 하락하는 건 당연합니다 .
즉, 단방향 데이터 흐름으로 인해 생기는 데이터 흐름 관리의 문제를 편리하게 하기 위해 Redux가 필요 !!
꼭 필요한 경우가 아닐 때는 redux 없이 구현하는 것이 더 낫습니다. 무엇이든지 그렇지만 필요할 때를 잘 알고 사용하는 것이 가장 중요합니다. 만약 React로 단방향 데이터 흐름을 구현할 경우 ‘과도한 prop drilling 현상이 생기거나 디버깅이 어려움이 생긴다면 redux가 필요한 상황입니다.
Redux 를 사용하기 전, 필수 개념 정리 !
액션 (action)
액션은 type 속성 값을 가진 자바스크립트 객체 형태로 되어있습니다.
액션 객체는 type 은 필수로 가지고 있어야 하고 그 외에 값은 마음대로 넣어줄 수 있습니다.
액션 생성함수는 단지 그 액션 객체를 생성하는 역할을 하는 함수입니다.
단순히 파라미터를 받아와서 액션 객체 형태로 만드는 구조입니다.
액션 객체를 사용할 곳에서 useDispatch()를 불러주고 dispatch 메서드안에 action객체를 넣어서 호출합니다.
디스패치 (dispatch)
디스패치는 액션을 발생시키는 함수입니다.
디스패치로 액션을 호출하면 스토어는 리듀서 함수를 실행시켜서 해당 액션을 처리하는 로직이 있다면 액션을 참고하여 새로운 상태를 만들어줍니다.
import { useDispatch } from 'react-redux';
위와같이 import 해준 후
const dispatch = useDispatch();
dispatch 메서드를 정의해준 뒤에
dispatch(deleteCart(cartItems));
위와 같은 방식으로 action객체를 호출해줄 수 있습니다.
*useDispatch 는 스토어의 내장 함수로, 스토어에 액션 객체를 전달하는 함수입니다.
dispatch의 인자로 액션 객체를 전달하는 것입니다.
dispatch가 실행되면 액션 객체는 리듀서에 전달되고, 리듀서 내에 미리 정의해둔 조건문과 action.type에 따라 스터어가 업데이트 됩니다.
리듀서 (reducer)
리듀서는 변화를 일으키는 함수 입니다.
위의 cartReducer 리듀서를 보시면 아시다시피 리듀서는 두개의 파라미터를 받습니다.
첫번째 매개변수로는 초기의 state값 즉, 현재의 상태를 받아오고, 두번째 매개변수로 action을 받습니다.
📣리듀서는 현재의 상태와 전달 받은 action을 참고하여 새로운 state를 만들어서 반환합니다.
스토어 (store)
리듀서에서는 한 애플리케이션 당 하나의 스토어를 만들게 됩니다.
스토어는 리덕스의 상탯값을 가지는 단일 객체이며, 프로젝트 어디서든 접근할 수 있습니다.
그렇게 하기 위해서는 Provider를 적용시켜주어야 합니다.
위와 같이 import 해주고 아래와 같이 Provider로 Routes 를 감싸줍니다.
useSelector 를 통해서 sotre의 특정내용을 가져올 수 있습니다.
reducer는 store의 key 값으로 작용합니다.
위쪽에서 봤었던 이 코드를 다시 보겠습니다.
items안에 store안의 값을 가져올 수 있고 이와 같이 store 값을 어느 위치에서든 불러올 수 있습니다.
그렇기 때문에 코드의 흐름에 대한 복잡성을 더이상 느낄 필요가 없겠죠 ?!
사실 개념을 이해하고 적용하는게 쉬울까 하는 생각이 더 들겠지만 개념을 이해하는게 반 이상이라..
완벽하게 이해하는 것이 더 중요하다고 생각합니다 !!
다음 글로는 미들웨어에 대한 정리를 해보도록 하겠습니다 .
Redux가 가진 특징 !
- 단 하나의 store 만을 가집니다 !
애플리케이션의 모든 상태는 하나의 스토어에서 관리됩니다.
데이터의 변경은 Reducer 를 통해서만 일어납니다.
- state 값은 불변성을 가지며 복사본을 이용해 데이터를 바꿔 주어야 합니다.
reducer에서 데이터를 바꿔주는 함수를 작성할 때, 이전의 데이터를 변경시키는 것이 아니라 새로운 데이터를 반환해주어야 합니다.
- reducer 는 순수함수여야 합니다.
*순수함수란 외부의 상태를 변경하지 않으면서 동일한 입력값에는 동일한 결과값을 반환하는 함수입니다.
reducer 은 이전의 데이터 상태와, action을 매개변수로 받습니다.
- reducer 는 여러개 존재할 수 있습니다.