커스텀 hooks 사용하기

Doum Kim·2020년 5월 14일
0

React - 기초

목록 보기
17/20
post-thumbnail

커스텀 hooks를 만들어서 반복되는 로직을 재사용할 수 있다.
다양한 hooks를 사용해서 원하는 기능을 구현해주고 컴포넌트에서 사용하고 싶은 값을 반환해주면 된다.

useInput.js

import { useState, useCallback } from 'react';

const useInput = (initialInputState) => {
  const [inputState, setInputState] = useState(initialInputState);

  const onChange = useCallback((e) => {
    const { name, value } = e.target;
    setInputState((inputState) => ({
      ...inputState,
      [name]: value,
    }));
  }, []);

  const reset = useCallback(() => {
    setInputState(initialInputState);
  }, [initialInputState]);
  return [inputState, onChange, reset];
};

export default useInput;

이렇게 만든 커스텀 hooks useInput을 사용하려면 아래와 같이 사용하면 된다.

import React, { useRef, useMemo, useCallback, useReducer } from 'react';
import UserList from './UserList';
import CreateUser from './CreateUser';
import useInput from './useInput'; //useInput 커스텀 hooks 불러오기

const countActiveUsers = (users) => {
  console.log('카운트');
  return users.filter((user) => user.active).length;
};

const initialState = {
  users: [
    {
      id: 1,
      username: 'Kim',
      age: 20,
      active: false,
    },
    {
      id: 2,
      username: 'Lee',
      age: '30',
      active: false,
    },
    {
      id: 3,
      username: 'Choi',
      age: '50',
      active: false,
    },
  ],
  inputs: {
    username: '',
    age: '',
  },
};

const reducer = (state, action) => {
  switch (action.type) {
    case 'CREATE_USER':
      return {
        inputs: initialState.inputs,
        users: [...state.users, action.user],
      };
    case 'REMOVE_USER':
      return {
        ...state,
        users: state.users.filter((user) => {
          return user.id !== action.id;
        }),
      };
    case 'TOGGLE_USER':
      return {
        ...state,
        users: state.users.map((user) => {
          return user.id === action.id
            ? { ...user, active: !user.active }
          : user;
        }),
      };
    default:
      return state;
  }
};

export default function App() {
  //useInput 사용법에 맞게 값 넣어주기
  const [{ username, age }, onChange, reset] = useInput({
    username: '',
    age: '',
  });
 
  const [state, dispatch] = useReducer(reducer, initialState);

  const { users } = state;

  const nextId = useRef(4);

  const onCreate = useCallback(
    (id) => {
      dispatch({
        type: 'CREATE_USER',
        user: { id: nextId.current, username, age },
      });
      nextId.current += 1;
      reset();
    },
    [username, age, reset],
  );

  const onRemove = useCallback((id) => {
    dispatch({ type: 'REMOVE_USER', id });
  }, []);

  const onToggle = useCallback((id) => {
    dispatch({ type: 'TOGGLE_USER', id });
  }, []);

  const count = useMemo(() => countActiveUsers(users), [users]);

  return (
    <div>
      <CreateUser
        username={username}
        age={age}
        onChange={onChange}
        onCreate={onCreate}
        />
      <div>activeUser : {count}</div>
      <UserList users={users} onRemove={onRemove} onToggle={onToggle} />
    </div>
  );
}

커스텀 hooks를 만들어서 사용하면 반복되는 로직을 분리해서 사용이 가능하다.

0개의 댓글