언제 useState를 사용하고, 언제 useReducer를 사용할까요?
여기에 답은 없습니다. 만약 컴포넌트에서 관리한는 값이 한개이고 간단하면 useState가 편합니다.
하지만 관리하는 값이 여러개이고 복잡해진다면 useReducer를 사용하는 것이 편리할 수 있습니다.
useReducer는 함수형 컴포넌트에서의 Redux를 어느정도 대신하는 역할을 합니다.
여러분들이 직접 사용해보고 편하신 것을 사용하는 것이 좋을 것 같습니다!
import React, { useRef, useReducer, useMemo, useCallback } from 'react'; import UserList from './UserList'; import CreateUser from './CreateUser'; function countActiveUsers(users) { console.log("활성 사용자 수를 세는중...") return users.filter(user => user.active).length } // 변수를 사용하여 현재 상태를 지정해줍니다. const initialState = { inputs: { username:"", email:"", }, users: [{ id: 1, username: 'Jongil', email: 'sji7532@gmail.com', active: true, }, { id: 2, username: 'Test1', email: '1@gmail.com', active: false, }, { id: 3, username: 'Sohn', email: '2@gmail.com', active: false, }] } function reducer(state, action) { // reducer 함수는 action의 type에 따라서 state를 어떻게 변경할건지 switch 문을 // 통해서 결정하게 됩니다. switch (action.type) { case 'CHANGE_INPUT': return { ...state, inputs:{ ...state.inputs, [action.name]: action.value } } case 'CREATE_USER': return { inputs: { username:"", email:"", }, users: state.users.concat(action.user) } case "TOGGLE_USER": return { ...state, users: state.users.map(user => user.id === action.id ? {...user, active: !user.active} : user) } case "REMOVE_USER": return { ...state, users: state.users.filter(user => user.id !== action.id) } default: throw new Error("Unhandled action"); } } function App() { const [state, dispatch] = useReducer(reducer, initialState) // useReducer를 사용하여 state와 state의 값을 변경할 dispatch를 선언합니다. // useReducer함수의 첫번째 인자는 처음에 만들어 놓은 reducer함수를 넘기고, // 두번째 인자에는 state의 최초값을 넘기게 됩니다. const nextId = useRef(4) const {users} =state const {username, email} = state.inputs const onChange = useCallback(e => { const {name, value} = e.target; dispatch({ type: 'CHANGE_INPUT', name, value }) }, []) const onCreate = useCallback(() => { dispatch({ type: "CREATE_USER", user : { id:nextId.current, username, email } }); nextId.current += 1 }) const onToggle = useCallback(id => { dispatch({ type: "TOGGLE_USER", id }) }, []) const onRemove = useCallback(id => { dispatch({ type:"REMOVE_USER", id }) }, []) const count = useMemo(() => countActiveUsers(users),[users]) return ( <> <CreateUser username={username} email={email} onChange={onChange} onCreate={onCreate} /> <UserList users={users} onToggle={onToggle} onRemove={onRemove} /> <div>활성 사용자 수: {count}</div> </> ); } export default App;
- fastcampus 벨로퍼트님 리액트 강의자료를 공부하며 정리하며 작성하였습니다.