useReducer란?
- useReducer는 상태 관리를 담당하는 훅을 말한다
- useState는 단순히 상태 관리를 해주는 훅이라면 useReducer는 해당 상태를 업데이트할때 유용한 Hook이다
- useReducer는 useState를 통한 상태 관리 + 상태 추가, 제거, 수정 등의 핸들러를 하나의 함수로 사용할 수 있도록 해준다
기본문법
const [state, dispatch] = useReducer(리듀서 이름, 초기 데이터)
state 데이터
- state는 상태 즉 데이터다
- useReducer 함수의 두번째 인자로 들어가는 초기 데이터를 1로 설정하면 state의 값도 1이 된다
- 즉 useReducer 함수에 등록한 초기데이터는 state로 접근할 수 있게 된다
dispatch 함수
- state를 처리하기 위한 함수다
- 데이터의 값을 추가, 제거, 수정을 위한 함수다
- dispatch 함수 안에 등록한 타입(추가, 제거, 수정 등)을 명시해주면 해당 로직이 실행된다
- 예를 들어 dispatch({type: 'ADD'}) 함수를 호출하면 데이터 추가 작업이 실행된다
- dispatch 함수의 인자로 특정한 작업 타입을 명시해주면 타입에 따라 등록한 함수를 실행해주는 역할을 한다
reducer 함수
- dispatch 함수에서 특정 type을 인자로 받을때 실행할 로직을 정해준다
- 아래의 코드처럼 reducer 함수를 생성하면 dispatch 함수의 인자로 {type: 'ADD'}가 들어왔을때 case 'ADD'인 로직이 실행된다
export function userReducer(state, action) {
switch (action.type) {
case 'ADD':
return [...state, action.data]
default:
throw new Error(`Unhandled action type: ${action.type}`)
}
}
action
- userReducer 함수의 두번째 인자로 들어 있는 값
- dispatch 함수 실행시 인자로 넣어준 값을 받아온다
- dispatch({type: 'ADD'})가 호출된 경우에는 action은 {type: 'ADD'} 객체가 되며 switch 검사문에서 받는 action.type은 'Add'가 된다
예제
userData.js
export const userData = [
{
id: 1,
name: 'Leanne Graham',
email: 'Sincere@april.biz',
},
{
id: 2,
name: 'Ervin Howell',
email: 'Shanna@melissa.tv',
},
{
id: 3,
name: 'Clementine Bauch',
email: 'Nathan@yesenia.net',
},
{
id: 4,
name: 'Patricia Lebsack',
email: 'Julianne.OConner@kory.org',
},
{
id: 5,
name: 'Chelsey Dietrich',
email: 'Lucio_Hettinger@annie.ca',
},
{
id: 6,
name: 'Mrs. Dennis Schulist',
email: 'Karley_Dach@jasper.info',
},
{
id: 7,
name: 'Kurtis Weissnat',
email: 'Telly.Hoeger@billy.biz',
},
{
id: 8,
name: 'Nicholas Runolfsdottir V',
email: 'Sherwood@rosamond.me',
},
{
id: 9,
name: 'Glenna Reichert',
email: 'Chaim_McDermott@dana.io',
},
{
id: 10,
name: 'Clementina DuBuque',
email: 'Rey.Padberg@karina.biz',
},
]
userList.jsx
import React, { useReducer, useRef, useState } from 'react'
import { userData } from '../constant/userData'
import { userReducer } from '../reducers/userReducer'
const UserList = () => {
const [userInput, setUserInput] = useState({
id: '',
name: '',
email: '',
})
const userInputHandler = (e) => {
const { name, value } = e.target
setUserInput({
...userInput,
[name]: value,
})
}
// const [state, dispatch] = useReducer(리듀서 이름, 초기 데이터)
const [state, dispatch] = useReducer(userReducer, userData)
const userId = useRef(11)
const addUser = (userInput) => {
dispatch({
type: 'ADD',
data: { ...userInput, id: userId.current },
})
userId.current += 1
}
const removeUser = (userId) => {
dispatch({
type: 'REMOVE',
data: { id: userId },
})
}
return (
<>
<div>
{state.map((user) => (
<div key={user.id}>
<p>{user.name}</p>
<button onClick={() => removeUser(user.id)}>제거하기</button>
</div>
))}
</div>
<input
type="text"
name="name"
placeholder="name"
onChange={userInputHandler}
/>
<input
type="email"
name="email"
placeholder="email"
onChange={userInputHandler}
/>
<button onClick={() => addUser(userInput)}>이름 추가</button>
</>
)
}
export default UserList
userReducer.js
export function userReducer(state, action) {
switch (action.type) {
case 'ADD':
return [...state, action.data]
case 'REMOVE':
return state.filter((el) => el.id !== action.data.id)
default:
throw new Error(`Unhandled action type: ${action.type}`)
}
}
App.jsx
import React from 'react'
import UserList from './components/UserList'
const App = () => {
return (
<div>
<UserList />
</div>
)
}
export default App
'React' 카테고리의 다른 글
[리액트] useEffect 4가지 사용법 간단 정리 (0) | 2022.08.23 |
---|---|
[리액트] useContext 정리 (0) | 2022.08.22 |
[리액트] 리액트에서 스타일 적용하는 5가지 방법 (인라인 스타일, CSS, SCSS, CSS Module, Styled-Components) (0) | 2022.08.12 |
[리액트] props를 className으로 지정하기 (0) | 2022.08.12 |
[리액트] 리액트 프로젝트에서 기본적인 ESLint, Prettier, setting.json 설정해주기 (0) | 2022.08.11 |
댓글