useState의 대체 함수로 useState처럼 state를 관리를 도와주는 리액트 훅 입니다.
그래서 useState와 약간 비슷합니다.
하지만 useState보다 더 많은 기능이 있고 더 복잡한 state에 유용합니다.
예를 들면 여러 state들이 함께 속해 있는 경우가 있습니다. 같은 것을 관리하는데 관리하는 측면이 다를 뿐인거죠 혹은 여러 state가 같이 바뀌거나 서로 관련된 경우가 있습니다.
그런 경우에는 useState나 거기에서 얻은 state는 종종 사용 및 관리가 어려워지거나 오류가 발생하기 쉽습니다.
이런 경우 useReducer를 useState 대신 쓸 수 있습니다.
하지만 그렇다고 해서 항상 useReducer를 사용해야 한다는 건 아닙니다.
더 강력하다고 해서 항상 더 좋다고 할 수는 없기 때문 입니다.
사용하기 조금 더 복잡하기 때문에 조금 더 설정이 필요해서 대부분의 경우에는 useState를 사용하는 것이 좋다고 생각합니다.
아래의 몇가지 예시를 보여드리며 useReducer의 사용 방법과 그리고 대부분의 경우에 useState를 사용하는 것이 좋은지에 대해서도 예시를 보여드리도록 하겠습니다.
useReducer 사용한 코드
import React, {useReducer} from 'react';
const reducer = (state, action) => {
if(action === 'Up') {
return state + 1;
} else if (action === 'Down') {
return state - 1;
} else if (action === 'Reset') {
return 0;
}
}
const Mark = () => {
const [count, dispatch] = useReducer(reducer, 0);
const down = () => {
dispatch('Down')
}
const reset = () => {
dispatch('Reset')
}
const up = () => {
dispatch('Up')
}
return(
<div>
<input type='button' value="-" onClick={down}/>
<input type='button' value="0" onClick={reset}/>
<input type='button' value="+" onClick={up}/>
<span>{count}</span>
</div>
)
}
export default Mark;
위의 코드는 useReducer를 사용한 간단한 예시 입니다. 조코딩님의 강의를 통해 가져온 예시로 사용법을 확인해 보면
Reducer는 State와 마찬가지로 구조분해 할당으로 state와 dispatch를 받아옵니다.
state는 우리가 앞으로 컴포넌트에서 사용할 상태를 가르키고 dispatch는 reducer의 action을 발생 시키는 함수 입니다.
dispatch는 dispatch({type: 'name' ...}) 처럼 많이 사용 합니다.
그리고 useReducer의 첫 번째 인자는 reducer 함수이고 두 번째 인자는 초기 상태 입니다.(useState 의 초기 상태와 같습니다.)
첫 번째 인자인 reducer 함수는 매개변수로 state와 action을 받습니다.
여기까지가 useReducer에 대한 설명이고 위의 예제를 다시 확인해 보면 useState를 쓰는게 더 효율적으로 보여집니다.
useState 사용한 코드
import React, {useState} from 'react';
const Mark = () => {
const [count, dispatch] = useState(0);
const down = () => {
dispatch(count - 1)
}
const reset = () => {
dispatch(0)
}
const up = () => {
dispatch(count + 1)
}
return(
<div>
<input type='button' value="-" onClick={down}/>
<input type='button' value="0" onClick={reset}/>
<input type='button' value="+" onClick={up}/>
<span>{count}</span>
</div>
)
}
export default Mark;
보시다 싶이 useState가 훨씬 간결하고 좋습니다.
위의 코드처럼 간단한 state가 아닌 더 강력한 state 관리가 필요한 경우 useReducer를 사용하는것이 좋습니다.
아래에 예시를 하나 더 보여드리도록 하겠습니다.
useReducer 예제 2
import React, {useState, useReducer} from 'react';
const initailState = {
count : 0,
students: [
]
}
const reducer = (state, action) => {
switch(action.type) {
case 'addStudent':
const name = action.payload.name;
const newStudent = {
id: Math.random().toString(),
name,
isHere: false,
}
return {
count : state.count +1,
students: [...state.students, newStudent]
}
case 'deleteStudent':
return {
count: state.count -1,
students: state.students.filter((students) =>
students.id !== action.payload.id),
};
case 'underlineName':
return {
students: state.students.map((student) => {
if(student.id === action.payload.id) {
return {...student, isHere: !student.isHere}
}
return student;
})
}
default:
return state
}
}
const RollBook = () => {
const [studentInfo, dispatch] = useReducer(reducer, initailState);
const [name, setName] = useState('');
return(
<React.Fragment>
<h1>출석부</h1>
<h3>총 학생 수: {studentInfo.count}</h3>
<input
type='text'
placeholder='이름을 입력해주세요'
value={name}
onChange={(event)=>{setName(event.target.value)}}
/>
<button
onClick={() => {dispatch({type: 'addStudent', payload: {name}})}}
>학생 추가</button>
{studentInfo.students.map(res =>
<div key={res.id}>
<span
style={{textDecoration: res.isHere ? 'line-through' : 'none', color: res.isHere ? 'gray' : 'black'}}
onClick={() => {dispatch({type: 'underlineName', payload: {id: res.id}})}}
>{res.name}</span>
<button
onClick={() => {dispatch({type: 'deleteStudent', payload: {id: res.id}})}}
>삭제</button>
</div>
)}
</React.Fragment>
)
}
export default RollBook;
이번에 작성한 코드는 별코딩님의 강의를 토대로 작성한 코드 입니다.
학생의 이름을 입력 하여 출석부를 만드는 기능 입니다.
위의 코드를 보면 useReducer를 사용하여 학생의 타입에 맞춰 학생을 추가, 삭제, 이름 지우기가 가능하도록 구현이 되어 있으며, useState를 사용하게 되었을때 보다 사용 및 관리하기가 훨씬 편해졌습니다.
'프로그래밍 > React' 카테고리의 다른 글
React useState 란? (0) | 2023.05.11 |
---|---|
React useEffect 란? (0) | 2023.05.08 |
React ref 란? (0) | 2023.04.27 |
React Portals이란? (0) | 2023.04.26 |
React Fragment란? (0) | 2023.04.26 |