※ 강의를 듣고 제가 이해한 내용을 바탕으로 정리한 것이라서 오류가 있을 수 있습니다.
React- 커스텀 HOOK 만들기
컴포넌트를 만들다보면 반복되는 로직이 자주 발생 하는데 그럴때 커스텀 HOOK을 만들어서 쉽게 재사용할 수 있다. 커스텀 훅을 만들때에는 use라는 키워드로 시작하는 파일을 만들고
그 안에 함수를 작성하면 되는데 그 안에서 useState, useEffect, useReducer, useCallback 등 Hooks 를 사용하여 원하는 기능을 구현해주고 컴포넌트에서 사용하고 싶은 값들을 반환해주면 된다.
useInputs.js
import { useState, useCallback } from 'react'; function useInputs(initialForm) { const [form, setForm] = useState(initialForm); // form이라는 상태를 만드는데 그 초기 값은 파라미터로 가져온 initialForm const onChange = useCallback(e => { const { name, value } = e.target; setForm(form => ({ ...form, [name]: value })); }, []); const reset = useCallback( () => setForm(initialForm), [initialForm]); // form을 리셋하는 함수 setForm의 파라미터는 초기값을 받아온 것을 설정해주겠다. return [form, onChange, reset]; // 3가지를 반환, 객체 형태로 써줘도 된다. }; export default useInputs;
위 코드는 input을 위해 만든 커스텀 훅이다.
App.js
import React, {useRef, useReducer, useMemo, useCallback} from 'react'; import UserList from './components/UserList'; import CreateUser from './components/CreateUser'; import useInputs from './components/useInputs'; // useInputs 불러옴 function countActiveUsers (users) { console.log('활성 사용자 수를 세는중...'); return users.filter(user => user.active).length; } const initialState = { users: [ { id: 1, username: 'progaramexplorer', email: 'progaramexplorer@naver.com', active: true }, { id: 2, username: 'tester', email: 'tester@gmail.com', active: false }, { id: 3, username: 'liz', email: 'liz@daum.net', active: false } ] } function reducer(state, action) { switch(action.type) { case 'CREATE_USER': return { inputs: initialState.inputs, 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('Unhandeled action'); } } function App() { const [state, dispatch] = useReducer(reducer, initialState); const [form, onChange, reset] = useInputs({ // form: 상태, onChange:이벤트, reset:초기화 함수, useInputs으로 대체 username:'', // 초기값 email:'', }); const { username, email } = form; const nextId = useRef(4); const {users} = state; const onCreate = useCallback(() => { dispatch({ type: 'CREATE_USER', user: { id: nextId.current, username, email, } }); nextId.current+= 1; reset(); // reset(); 호출 }, [username, email, reset]) 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;
만든 커스텀 훅을 사용하기 위해서 useReducer에서 기존의 inputs을 useIputs으로 대체해주고
새로운 항목을 추가 할 때 input 값을 초기화해야 하므로 데이터 등록 후 reset() 을 호출해줘야한다.
이렇게 커스텀 Hook 을 만들어서 사용하면 컴포넌트의 로직을 분리시켜서 필요 할 때 쉽게 재사용 할 수도 있다.
'개발 공부한 내용 정리 > React' 카테고리의 다른 글
React- 클래스형 컴포넌트로 카운터 만들기 (0) | 2020.10.01 |
---|---|
React- 클래스형 컴포넌트 선언 (0) | 2020.09.29 |
React- React.memo 를 사용한 컴포넌트 리렌더링 방지 (0) | 2020.09.26 |
React- useCallback을 사용하여 함수 재사용 하기 (0) | 2020.09.24 |
React- useMemo 를 사용하여 연산한 값 재사용하기 (0) | 2020.09.12 |