이 글은 아래 포스팅을 번역한 글입니다.
https://blog.logrocket.com/why-use-redux-reasons-with-clear-examples-d21bffd5835/
----
목차
- Redux
- Redux를 언제 사용해야 할까
- Redux가 필요한 이유
- Redux의 동작 방식
- Actions
- Reducer
- Store
- Middleware
- 결론
1. Redux
리덕스는 JavaScript 앱이 일관성 있고, 테스트하기 쉽도록 돕는 예측 가능한 상태 컨테이너입니다.
리액트에선 대부분 상태 관리 도구로 사용되고 있고, 다른 JavaScript 프레임워크나 라이브러리에서도 사용할 수 있습니다.
리덕스를 사용하면 앱의 상태를 스토어에 저장하고, 각 컴포넌트들이 스토어에 저장된 상태에 접근할 수 있습니다.
2. Redux를 언제 사용해야 할까
리덕스는 앱의 상태를 스토어라는 하나의 공간에서 관리할 수 있게 해주고, 예측과 추적이 가능한 앱을 만들 수 있게 해줍니다.
하지만, 이러한 이점에는 절충과 제약이 따릅니다. 소 잡는 칼로 닭을 잡는다는 말이 있듯이, 단순하게 구현이 가능한 부분도 리덕스로 인해 복잡하게 변할 수 있기 때문입니다.
리덕스를 언제 사용해야 될지에 대한 심플한 답변은, 리덕스가 필요할 때 스스로가 깨닫게 된다는 것입니다.
리덕스가 필요한지 여전히 고민된다면, 필요하지 않은 것입니다.
하지만, 앱의 규모가 커져서 상태를 관리하기가 복잡해지면, 앱을 더 쉽고 간단하게 만드는 방법을 찾게 될 것입니다.
3. Redux가 필요한 이유
상태 관리는 컴포넌트 간 데이터를 공유하고 통신을 하게 하는 방법입니다.
Rect, Angular와 같은 대부분의 라이브러리들은 외부 라이브러리나 도구 없이 상태를 관리할 수 있도록 빌드됩니다.
이는 컴포넌트가 몇 개 없을 땐 잘 동작하지만, 앱이 커지면 상태를 관리하기가 더욱 어려워집니다.
컴포넌트끼리 데이터를 공유하는 앱에선, 앱의 상태가 어디에 있어야 하는지 아는 게 어려울 수 있습니다. 이상적으로는 컴포넌트의 데이터가 하나의 컴포넌트에만 있어야 하므로, 다른 컴포넌트와 데이터를 공유하는 게 어려워집니다.
위 사진의 빨간 컴포넌트들이 데이터를 공유하려면 데이터를 상위 컴포넌트로 전달해서 다른 컴포넌트에게 전달해야 할 것입니다. 이런 구조는 상태를 유지하기 어렵게 만들고, 예측하기 힘들게 만듭니다. 또한 중간의 컴포넌트들이 데이터를 전달해주는 역할도 해줘야 하겠죠.
앱이 복잡해짐에 따라 상태 관리가 엉망이 된다는 것은 분명합니다. 이것이 상태를 더 쉽게 관리할 수 있게 해주는 리덕스가 필요한 이유입니다.
4. Redux의 동작 방식
리덕스가 동작하는 방식은 간단합니다. 앱의 상태를 저장하는 스토어가 있고, 각 컴포넌트는 데이터를 다른 컴포넌트에 전달할 필요 없이, 스토어에 저장된 상태에 접근할 수 있습니다.
리덕스의 구성요소로는 액션, 스토어, 리듀서 세 가지가 있습니다. 이 구성요소들은 리덕스의 이점을 이해할 수 있게 돕고, 리덕스를 어떻게 사용해야 하는지 이해하는 데 중요한 요소입니다.
5. Actions
쉽게 말하면, 액션은 이벤트입니다. 액션은 리덕스 스토어로 데이터를 전달할 수 있는 유일한 방법입니다.
액션은 'store.dispatch()'라는 함수를 사용해 보내집니다. 액션은 순수한 JavaScript Object이며 액션의 type을 나타내는 type이라는 프로퍼티를 가져야 합니다. 또한, 액션에 의해 동작해야 할 정보가 포함된 페이로드를 가져야 합니다.
예를 들면 아래와 같습니다.
{
type: "LOGIN",
payload: {
username: "foo",
password: "bar"
}
}
액션 생성자의 예는 아래와 같습니다.
const setLoginStatus = (name, password) => {
return {
type: "LOGIN",
payload: {
username: "foo",
password: "bar"
}
}
}
앞서 설명했듯이, 액션은 반드시 type과 스토어에 저장될 페이로드를 가져야 합니다.
(페이로드 프로퍼티의 이름은 꼭 payload가 아니어도 됩니다.)
6. Reducer
리듀서는 앱의 현재 상태 값을 가져오고, 액션을 실행하고, 새 상태 값을 반환하는 순수 함수입니다.
이러한 상태는 Object로 저장되며 저장소에 보낸 작업에 대한 응답으로 앱의 상태가 변경되는 방식을 지정합니다.
아래는 리듀서가 어떻게 동작하는지에 대한 예입니다.
const LoginComponent = (state = initialState, action) => {
switch (action.type) {
case "LOGIN":
return state.map(user => {
if (user.username !== action.username ) {
return user;
}
if (user.password == action.password) {
return {
...user,
login_status: "LOGGED IN"
}
}
});
default:
return state;
}
}
리듀서는 순수 함수로서, 전달된 Object의 데이터를 변경하거나 앱의 Side Effect를 수행하지 않습니다. 동일한 Object가 주어지면, 항상 동일한 결과를 반환해야 합니다.
7. Store
스토어는 앱의 상태를 가지고 있습니다. 리덕스를 사용하는 앱은 하나의 스토어만을 유지하는 것이 권장됩니다.
스토어를 사용해 상태에 접근하고, 상태를 갱신하고, 리스너를 등록하고나 해제할 수 있습니다.
아래는 스토어를 생성하는 예입니다.
const store = createStore(LoginComponent);
상태에 대해 수행된 액션은 항상 새 상태를 반환합니다. 따라서, 상태를 예측하기가 쉬워집니다.
8. Middleware
리덕스는 dispatch된 모든 액션들이 리듀서로 전달되기 전에 가로챌 수 있게 해줍니다. 이 가로채기는 미들웨어를 통해 수행됩니다.
구체적으로, 미들웨어는 액션과 리듀서 사이의 중간 요소이며, 액션을 디스패치 했을 때 리듀서에서 처리하기 전에 지정된 작업을 실행할 수 있게 해줍니다.
예제 코드는 아래와 같습니다.
function simpleMiddleware({ getState, dispatch }) {
return function(next) {
return function(action) {
...
}
}
}
9. 결론
리덕스에 대한 주요 특징과 앱에 적용했을 때의 이점을 알아봤습니다. 리덕스를 사용하면 이점이 있지만, 모든 앱에 리덕스를 적용해야 하는 것은 아닙니다. 리덕스가 없이도 앱은 여전히 잘 동작할 수 있기 때문입니다.
리덕스의 주요 이점 중 하나는 "상태에 무엇이 일어났는가"와 "상태가 어떻게 변경됐는가"를 분리하는 것입니다. 하지만, 프로젝트에 상태 관리 도구가 필요하다고 판단되는 경우에만 리덕스를 적용해야 합니다.
'JavaScript > Redux' 카테고리의 다른 글
Redux - 고급 사용법 (0) | 2022.04.20 |
---|---|
Redux - react-redux (0) | 2022.04.18 |
Redux - 사용해보기 (0) | 2022.03.19 |