Tech Blog of Pinomaker

우리가 어떠한 상태를 관리할 때는 useState()를 사용해서 해왔지만, useState()는 컴포넌트 내부에서 이루어진다는 것이 있다. 그러기에, A 컴포넌트에서 B 컴포넌트로 상태 전달할 때의 어려움도 존재하였다.

 

이를 해결 하는 방법이 useReducer다. useReducer는 컴포넌트의 상태 업데이트 로직을 컴포넌트에서 분리 시킬 수 있기에, 컴포넌트 바깥에 작성하거나, 다른 파일에서 작성 하고 불러와서 사용할 수도 있다.

 

useReducer에서 reducer는 현재 상태(state)와 액션 객체(action)를 파라미터로 받아 새로운 상태를 반환하는 함수다.

reducer에서 반환하는 상태는 곧 컴포넌트가 가지게 될 새로운 상태가 된다. 여기서 action은 상태를 업데이트를 하기 위한 정보를 가지고 있으며, 주로 type 값을 지닌 객체로 사용하긴 하지만 반드시 따라야하는 규칙은 없다.

<javascript />
function reducer(state, action) { /** * 새로운 상태를 만드는 로직 * 그 후 새로운 상태를 만들어서 반환 */ return nextState; }

 

아래의 코드를 보면, action 객체의 형태는 자유인 것을 볼 수 있다. 주로 type 값을 대문자와 -를 이용해서 작성하는 관습이 있지만, 반드시 따라야하는 것은 아니다.

<javascript />
// 카운터에 1을 증가하는 action { type: 'INCREMENT' } // 카운터에 1을 감소하는 action { type: 'DECREMENT' } // input 값을 바꾸는 액션 { type: 'CHANGE_INPUT', key: 'name', value: 'pino' }

 

 

reducer에 대해서 알아봤으니, useReducer의 사용 방법에 대해서 알아보자.

<javascript />
const [state, dispatch] = useReducer(reducer, initialState)

 

useReducer는 위의 형태로 사용하게 되는 데,  state는 우리가 컴포넌트에서 사용 할 수 있는 상태이며, dispatch는 액션을 발생 시키는 함수인데, 아래와 같이 사용하게 된다.

<javascript />
dispatch({ type: 'INCREMENT' })

 

useReducer에 넣는 첫번째 인자는 reducer 함수이고, 두번째는 초기 상태다.

 

우리는 숫자를 증가, 감소 시키는 컴포넌트를 예제로 작성해보자.

아래의 예제는 증가 버튼을 누르면 숫자가 1 증가하고, 감소 버튼을 누르면 숫자가 1 감소하는 예제이며, 일단 useState를 활용하여 숫자를 관리한다.

<javascript />
import React, { useState } from 'react' export default function Counter() { const [number, setNumber] = useState(0) const onIncrease = () => { setNumber(current => current + 1) } const onDecrease = () => { setNumber(current => current - 1) } return ( <div> <h1>{number}</h1> <button onClick={onIncrease}>증가</button> <button onClick={onDecrease}>감소</button> </div> ) }

 

아래의 코드는 useState가 아닌 useReducer를 활용하여, 상태를 관리한 예제다.

먼저 reducer 함수를 생성하며, action type이 "INCREMENT"일 경우는 상태를 1 증가, "DECREMENT"일 경우에는 1 감소를 시키고 상태를 반환한게 만들고, useReducer를 이용해서 컴포넌트 내부에 생성한 리듀서를 이용하여 상태를 관리할 수 있게 된다.

<javascript />
import React, { useReducer } from 'react' const reducer = (state, action) { switch (action.type) { case 'INCREMENT': return state + 1 case 'DECREMENT': return state - 1 default: return state } } export default function Counter() { const [number, dispatch] = useReducer(reducer, 0) const onIncrease = () => { dispatch({ type: 'INCREMENT' }) } const onDecrease = () => { dispatch({ type: 'DECREMENT' }) } return ( <div> <h1>{number}</h1> <button onClick={onIncrease}>증가</button> <button onClick={onDecrease}>감소</button> </div> ) }

 

 

'F.E > React' 카테고리의 다른 글

MSW로 Mocking(1) - Brower  (0) 2023.09.23
[React] Cookie + JWT + axios 이용하여 JWT 인증하기.  (0) 2022.09.08
[React] useCallback 사용하기.  (0) 2022.08.26
[React] useMemo 사용하기.  (0) 2022.08.26
[React] useRef 사용하기.  (0) 2022.08.21
profile

Tech Blog of Pinomaker

@pinomaker

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!