-
Redux 란 무엇인가?React 2022. 8. 30. 16:01
1. 리엑트 컨텍스트(React-Contexst)
리덕스를 알아보기 전에 먼저 리엑트 컨텍스트(React-Contexst)를 알아보겠습니다.
컨텍스트는 컴포넌트간에 props를 일일이 전달하는 props drilling 현상 개선하기 위해 사용합니다.
리엑트 공식문서에는 아래와 같이 나와있습니다.
context - 리액트 공식문서 정리하자면, props를 전달할 때 부모에서 자식으로 전달해야하는 번거로움이 있는데, 이를 해결할 수 있는 것이 바로 리엑트 컨텍스트인 것입니다.
2. 리엑트 컨텍스트(React Context)의 단점
하지만 리엑트 컨텍스트는 두가지 단점이 존재합니다.
- 복잡한 설정과 관리
첫번째 단점은 리엑트 컨텍스트를 사용하면 설정이 아주 복잡해 질 수 있고, 상태관리가 복잡해질 수 있다는 것입니다.
그 복잡성은 구축하는 애플리케이션의 종류에 따라 달라질 것입니다. 소형 또는 중형 애플리케이션은 대부분 문제가 되지 않을 가능성이 높습니다. 하지만 대형 애플레케이션을 구축하는데 리액트 컨텍스트를 사용하면 결국 이런 코드가 나올 수 있습니다.다양하고 많은 컨텍스트가 있고, 다수의 컴포넌트나 전체 앱에 영향을 미치는 많은 다양한 상태가 있습니다.
그래서 그런 상태들을 관리하기 위해 구축한 ContextProvider 컴포넌트가 아주 많이 있게 됩니다.그래서 결과적으로 위처럼 아주 심하게 중첩된 JSX코드가 나오게 됩니다 물론 위처럼 다양하고 많은 Contextprovider를 구축할 필요는 없습니다. 그저 모든 상태들을 관리하기 위한 큰 컨텍스트 하나와, ContextProvider 컴포넌트 하나만 사용할 수 있습니다. 하지만 그렇게 하면 큰 ContextProvider 컴포넌트 하나가 다양하고 많은 것들을 관리하기 때문에 그것 자체를 유지하고 관리하기가 어려워질 수 있습니다. 큰 컨텍스트 하나가 인증,테마,사용자입력,모달표시 뿐만 아니라 다른 많은 상태들도 관리해야 할 겁니다. 그래서 그게 단점이 될 수 있습니다.
2. 성능 이슈
먼저 리엑트 팀원이 올린 공식 언급을 살펴보겠습니다.
위 글을 요약해보자면, 리엑트 컨텍스트는 테마를 변경하거나 인증 같은 저빈도 상태관리에는 아주 좋지만, 데이터가 자주 변경되는
고빈도 상태 관리에는 좋지 않다고 언급하고 있습니다. 리엑트 컨텍스트만을 이용하여 상태 관리를 한다면, 성능이 나쁠 수 있다는 것 입니다. 즉 리액트 컨텍스트가 모든 시나리오와 모든 경우에서 리덕스를 훌륭하게 대체할 수 없다고 말하고 있습니다.
중요한점은 소형 또는 중형 정도의 프로젝트, 심지어 다수의 대형 앱에서도 위의 단점이 상관없을 수도 있습니다.
그러나 리엑트 컨텍스트의 한계점이 있다는 점을 분명히 알아두는 것이 중요하다고 볼 수 있겠습니다.
그래서 리엑트 컨텍스트의 대안으로 리덕스를 사용합니다.
3. 리덕스
자 이제 리덕스에 대해 알아보겠습니다. 위에서 살펴보았듯이 리덕스는 리액트 컨텍스트의 대안이라고 할 수 있습니다.
리덕스의 작동방식
리덕스는 애플리케이션에 있는 하나의 중앙 데이터(상태) 저장소입니다. 리덕스는 정확히 한 개의 저장소를 갖습니다. 그 저장소에 전체 애플리케이션의 모든 상태를 저장합니다. 그리고 그 저장소에 인증 상태, 테마, 입력상태 등 무엇이든 저장 할 수 있습니다.
그러면 "하나의 저장소면 관리가 어렵지 않나?" 하는 생각이 들 수 있습니다. 하지만 리덕스에서는 중앙저장소 전체를 항상 직접 관리할 필요가 없습니다.
궁극적으로는 중앙 저장소에 데이터를 저장해서 컴포넌트 안에서 사용할 수 있습니다.
예를 들어 상태가 변경되면 컴포넌트에서 그걸 인지해서 그에 맞춰 대응하고 UI를 업데이트하길 원한다고 했을 때,
이 컴포넌트를 위해 중앙 저장소에 대한 구독을 설정합니다. 컴포넌트가 저장소를 구독하고 데이터가 변경될 때마다 저장소가 컴포넌트에 알려주게 됩니다. 그러면 컴포넌트는 필요한 데이터를 받게 됩니다. 리덕스 저장소의 일부를 받게 되는 것입니다.
이런식으로 컴포넌트에서 데이터를 받게 됩니다.
그렇다면 이제 중요한 것은 데이터를 어떻게 변경할 것인가 하는 문제입니다. 데이터(상태)를 변경할 방법이 필요합니다.
그럼 어떻게 데이터를 변경할 수 있을까요?
여기서 중요한 규칙이 있습니다.
컴포넌트는 절대로 중요하지 않고, 절대로 저장된 데이터를 직접 조작하지 않습니다. 그래서 구독을 하는 것이고,
데이터는 절대로 반대 방향으로 흐르지 않습니다. 또한 컴포넌트는 저장소에 있는 데이터를 직접 조작하지 않습니다.
그 대신에 리듀서라는 개념을 이용합니다. 리듀서 함수를 이용하여 데이터를 변경할 수 있습니다.
이 리듀서 함수는 중앙 저장소의 데이터를 변경하는 함수 입니다.
리듀서 함수는 입력을 받아서 그 입력을 변환하고 내보내는 그런 일반적인 함수 입니다.
지금까지 데이터를 변경할 수 있는 리듀서와, 중앙 저장소 그리고 저장소를 구독하고 있는 컴포넌트에 대해 알아보았습니다.
이제 컴포넌트와 리듀서 함수를 연결하는 일이 남아 있습니다.
왜 연결해야 할까요? 왜냐하면 결국 데이터 변경을 발생시키는 것은 컴포넌트이기 때문입니다.
그럼 연결 방법에 대해 알아보겠습니다.
컴포넌트는 액션을 발송합니다. 그래서 컴포넌트가 액션을 발생시킨다고 말할 수 있습니다. 여기서 액션은 사실 단순한 자바스크립트 객체입니다. 그 안에 리듀서가 수행해야 할 작업을 설명하게 됩니다. 그래서 리덕스는 그 액션을 리듀서로 전달하고, 리덕스는 그 액션을 리듀서로 전달합니다. 이어서 그 작업을 리듀서가 수행하게 됩니다.
정리하자면 컴포넌트가 리듀서에 액션을 전달 -> 리듀서는 데이터(상태)를 변경 -> 중앙 저장소의 데이터가 변경 -> 중앙 저장소를 구독중인 컴포넌트가 UI를 업데이트 하게 됩니다.
바로 이것이 리덕스의 작동 방식입니다.
리덕스의 작동방식 'React' 카테고리의 다른 글
setState() 비동기 문제해결 (0) 2022.11.06 [React] useEffect (0) 2022.06.15 [React] state lifting(끌어올리기) (0) 2022.06.14