※ 강의를 듣고 제가 이해한 내용을 바탕으로 정리한 것이라서 오류가 있을 수 있습니다.
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 |