useReducer란 useState 보다 더 다양한 컴포넌트 상황에서 더 다양한 상태를 다루고 싶을 때 사용하는 훅 입니다
리듀서는 현재 상태와 업데이트를 위해 필요한 정보를 담은 액션을 파라미터로 전달받아 새로운 상태를 반환하는 함수입니다
리듀서 에서 새로운 상태를 만들 때는 반드시 불변성 을 지켜주어야 합니다
reducer의 기본형태
function reducer(state, action) {
return {...};
}
액션의 기본 형태
{
type: 'INCREMENT'
}
다음 예제를 통해서 더 자세히 알아봅시다
Counter.js
import React, {useReducer} from 'react';
function 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;
컴포넌트 밖에서 reducer 함수를 만들어주고 안에는 action의 타입에 따라 상태값을 반환하는 스위치문을 작성해준다
useReducer의 기본 형태는 아래와 같고
const [state, dispatch] = useReducer(reducer, {value: 0})
state는 현재 상태를 가리키며 dispatch는 액션을 발생시키는 함수이다
useReducer는 첫번째 인자로 reducer 함수를 두번째 인자로 reducer의 기본값을 넣어준다
useReducer를 사용할 때의 가장 큰 장점으로는 컴포넌트 업데이트 로직을 컴포넌트 밖에 빼서 모듈화 할 수 있다는데 있다
인풋이 여러개 일때 reducer 사용
import React, {useReducer} from 'react';
function 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>
<b>이름 : {name}</b>
</div>
<div>
<b>닉네임 : {nickname}</b>
</div>
</div>
)
}
export default Info;
action 값은 어느것이든 다 가능하다, 위 예제처럼 심지어 이벤트 객체가 가지고 있는 값도 액션 값으로 사용할 수 있다