커스텀 hooks를 만들어서 반복되는 로직을 재사용할 수 있다.
다양한 hooks를 사용해서 원하는 기능을 구현해주고 컴포넌트에서 사용하고 싶은 값을 반환해주면 된다.
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를 만들어서 사용하면 반복되는 로직을 분리해서 사용이 가능하다.