useReducer는 useState와 비슷하게 함수형 컴포넌트에서 State값을 컨트롤 할때 사용하는 Hook 인데, useState 더 다양한 상황에서 사용 할 수 있다.
그리고 리듀서는 현재 상태, 그리고 업데이트를 위해 필요한 정보를 담은 액션 값을 전달받아 새로운 상태를 반환하는 함수이다. 그리고 리듀서를 이용하여 상태에 변화를 줄 때는 반드시 불변성을 지켜주어야 한다.
리듀서 함수는 다음과 같이 구성한다.
const reducer = (state, action) => {
return{};
}
};
이런식으로 리듀서 함수를 작성하고, useReducer 훅을 이용하여 이 함수를 사용한다.
리액트의 기초 예제인 카운터 예제 코드를 보면,
import React, { useReducer, useState } from "react";
const reducer = (state, action) => {
switch (action.type) {
case "INCREMENT":
return { value: state.value + 1 };
case "DECREMENT":
return { value: state.value - 1 };
default:
return state;
}
};
const Counter = () => {
const [state, dispatch] = useReducer(reducer, { value: 0 });
return (
<div>
<p>
현재 카운터 값은 <b>{state.value}</b>입니다.
</p>
<button onClick={() => dispatch({ type: "INCREMENT" })}>+1</button>
<button onClick={() => dispatch({ type: "DECREMENT" })}>-1</button>
</div>
);
};
export default Counter;
여기서
const [state, dispatch] = useReducer(reducer, { value: 0 });
이 부분이 리듀서 함수를 사용하는 부분이다.
useReducer의 첫번째 파라미터에는 사용 할 리듀서 함수를 넣고, 두번째 파라미터에는 기본 state값을 넣어준다.
useReducer를 사용하면 state, dispatch 두가지를 받아오는데, state는 두번째 파라미터로 설정해준 값이 들어가고,
dispatch는 액션을 발생시키는 함수이다.
<button onClick={() => dispatch({ type: "INCREMENT" })}>+1</button>
<button onClick={() => dispatch({ type: "DECREMENT" })}>-1</button>
위의 카운터 예제에서 dispatch 함수를 사용하는 부분인데, 파라미터로 액션타입을 넣어주면, 리듀서 함수의 switch문에서 이때 넘겨받는 action값을 기준으로 동작한다.
useReducer를 사용하여 state를 관리할때 장점은, state를 관리하는 부분을 컴포넌트 바깥으로 뺄 수 있다는 장점이 있다.
useState를 사용하여 state값을 제어 할때는, 컴포넌트 안에 넣어서 관리를 했어야했다. 하지만 useReducer를 사용하면, 위의 카운터 예제처럼 컴포넌트 밖에서 제어할 수 있다!
그리고 위 예제에선 스위치문을 이용하여 액션값을 받고, 그에 맞는 상태변화를 리턴해줬는데, 꼭 스위치문에 따라서 리턴해주지않아도 된다.
import React, { useEffect, useReducer, useState } from "react";
const reducer = (state, action) => {
return {
...state,
[action.name]: action.value
};
};
const Info = () => {
const [state, dispatch] = useReducer(reducer, { name: "", nickname: "" });
const { name, nickname } = state;
const onChange = (e) => {
dispatch(e.target);
};
return (
<div>
<div>
<input name="name" value={name} onChange={onChange} />
<input name="nickname" value={nickname} onChange={onChange} />
</div>
<div>
<div>
<b>이름:</b> {name}
</div>
<div>
<b>닉네임:</b> {nickname}
</div>
</div>
</div>
);
};
export default Info;
e.target 값을 dispatch 해주게되면, 리듀서 함수의 action에 e.target값이 들어가게되고, 전달받은 e.target 값을 참고하여
[e.target.name] : e.target.value 로 상태변화를 주게되는것!
(dispatch에서 넘겨주는 파라미터값이 리듀서 함수에서 action 이라고 생각!)
이런식으로 사용할 수 도있다. useReducer에서 액션은 어떤 값도 사용이 가능하기때문이다.
* velopert 님의 리액트를 다루는 기술 서적을 참고하여 정리한 글입니다 *
'프로그래밍 > React' 카테고리의 다른 글
React - 원신 뮤직플레이어! (Genshin Player) (0) | 2021.11.06 |
---|---|
React - useCallback (0) | 2021.09.01 |
React - useRef() 그리고 useEffect의 ComponentWillUnmount (0) | 2021.08.26 |
React - useEffect (0) | 2021.08.26 |
React - useState (0) | 2021.08.26 |