[JavaScript] React - useReducer

손종일·2020년 10월 5일
0

React

목록 보기
18/22
post-thumbnail

React

useReducer 사용해보기

언제 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 벨로퍼트님 리액트 강의자료를 공부하며 정리하며 작성하였습니다. 
profile
Allday

0개의 댓글