본문 바로가기

Libraries/React

[React] useReducer로 복잡한 상태변화 로직을 컴포넌트로부터 분리하기

728x90

 

useReduer를 사용해서 복잡한 상태변화 로직을 컴포넌트로부터 분리하기

 

 

 

 useReducer 

 

 

위 사진에서 보다시피, App.js 컴포넌트 안에 굉장히 많은 상태변화함수 (onCreate, onEdit, onRemove)가 존재하는 상태이다.

그리고 이 상태변화함수들은 컴포넌트 내에만 존재해야만한다.

상태를 업데이트 하기 위해서는 기존의 상태를 참고해야하기 때문이다.

그런데 컴포넌트의 코드가 길어지고 무거워지는건 결코 좋지 않다.

그래서 복잡하고 긴 상태변화 로직을 컴포넌트 바깥으로 분리해야한다.

그때 사용하는 것이 useReducer이다.

 

 

 

 

위 사진에는 useState만 사용해서 1부터 10000까지 각각 더할 수 있는 Counter가 있다.

그리고 10, 10, 100, 1000, 10000을 더할 수 있는 버튼 5개와 상태 변화 함수 5개가 있다. 

이렇게 useState를 이용하면 상태변화함수 5개를 각각 모두 다 Counter 컴포넌트 안에 작성을 해야해서 컴포넌트 코드가 길어지고 복잡해질 수밖에 없다.

실제로 개발을 진행하다보면 state가 하나의 컴포넌트에 매우 많아질텐데, 이렇게 컴포넌트를 무겁게 사용하는건 좋지 않은 방법이다.

 

 

 

 

그래서 useRucer를 사용하면 useState를 대체할 수 있다.

위 사진처럼 왼쪽 reducer라는 상태변화함수를 컴포넌트 바깥으로 분리해서 다양한 상태변화 로직을 switch case문처럼 쉽게 처리할 수 있게 바꿀 수 있다.

 

<코드 설명>

 

 const Counter = () => { const [count, dispatch] = useReducer(reducer, 1);

이런식으로 비구조화할당을 통해 사용하고, 배열 [count, dispatch]를  반환한다. 

 

 const [count, dispatch]

0번째 인덱스인 count는 state의 역할을 한다.

1번째 인덱스인 dispatch는 useState처럼 상태를 변화시키는 함수이다.

 

 useReducer(reducer, 1);

그리고 useReducer라는 함수를 호출할 때는 1번째 인자로 reducer라는 함수를 전달해줘야한다.

reducer는 (dispatch가 일으킨) 상태변화를 처리하는 역할을 한다.

2번째 인자에는 counter state의 초기값이 들어간다. 

 

 const Counter = () => { const [count, dispatch] = useReducer(reducer, 1);

정리하자면, count라는 state를 만들게되면, 초기값이 1로 할당이 되고,

1이라는 값(count의 state)을 변경하고 싶다면, 상태변화함수인 dispatch를 호출해서 상태 변화를 일으키면, 상태변화처리함수인 reducer가 처리를 하게된다.  

 

 

 

 상태변화가 일어나는 로직 살펴보기 

 

 

 <button onClick={() => dispatch({ type: 1 })}>add 1</button>

dispatch가 "add 1"이라는 버튼을 누르면 호출이 되는데,

dispatch 함수를 호출하면서 상태변화가 일어나고, reducer로 { type: 1 } 이라는 객체를 전달하게된다.

이 객체는 "action객체" 라고 부르고, 객체에는 꼭 type이라는 프로퍼티가 들어있다. (action은 곧 상태변화임. 즉, 상태변화를 설명하는 객체라고 생각하면 됨)

결국 dispatch가 호출이 되면, 상태변화가 일어나야하고, 그 상태변화에 대한 처리는 reducer가 수행하는 것이다.

 

const reducer = (state, action) => {
 switch (action.type) { 
  case 1: 
   return state + 1;
 } 
};

이 reducer 함수는 dispatch가 일어나면 상태변화에 대한 처리를 하기 위해서 호출이 되는데,
1번째 인자로는 현재 가장 최신의 state를 받고,
2번째 인자로는 dispatch를 호출할 때 전달해줬던 action객체를 전달 받게된다.

즉, "add1" 버튼을 누르면 dispatch가 호출되면서, reducer 함수가 실행되는데, reducer 함수가 받게 되는 1번째 인자인 state는 1이 되고, 2번째 인자인 action 객체는 { type: 1 } 이라는 객체를 받게 되는 것이다.

reducer 함수에서는 switch case문을 이용해서 action의 type에 따라서 각각 새로운 state를 반환하게된다.

 결국, case1에서는 state=1을 받아서 1+1인 2를 반환하고, 이것이 새로운 state가 되어 다시 count에 들어가는 것이다.

 

 

 

 그림으로 한눈에 보기 

 

 

 

 

useReducer를 구체적으로 어떻게 사용하는지 궁금하다면 아래 게시글을 참고하세요! 

 

https://dev-ini.tistory.com/98

 

[React] useReducer를 코드에 적용하기 (emotion diary 프로젝트 2탄)

useReducer 개념을 알아야 이해가 가기 때문에 아래 게시글을 보고 오시길 바랍니다! https://dev-ini.tistory.com/89 [React] useReducer로 복잡한 상태변화 로직을 컴포넌트로부터 분리하기 useReduer를 사용해서

dev-ini.tistory.com

 

 

728x90