use
를 붙이는 것이 관례 custom Hooks
은 다른 Hook
을 호출하여 사용할수 있다.※주의사항
너무 이른 단계에서 로직을 뽑아내려고 하지는 않는 게 좋습니다.
함수 컴포넌트가 할 수 있는 일이 더 다양해졌기 때문에 여러분의 코드에 있는 함수 컴포넌트의 길이도 길어졌을 것입니다.
이는 지극히 평범한 일이며 지금 바로 Hook으로 분리해야만 한다고 느낄 필요는 없습니다.
하지만 동시에 사용자 정의 Hook이 복잡한 로직을 단순한 인터페이스 속에 숨길 수 있도록 하거나 복잡하게 뒤엉킨 컴포넌트를 풀어내도록 돕는 경우들을 찾아내는 것을 권장합니다.
const useInput = (initialValue, validator) => {
const [value, setValue] = useState(initialValue);
const onChange = e => {
const {target: {value:targetValue}} = e;
const willUpdate = typeof validator === 'function'
? validator(value)
: true;
if (willUpdate) {
setValue(targetValue);
}
}
return { value, onChange };
}
const App = () => {
const maxLength = value => value.length < 10;
const name = useInput("woong", maxLength);
return (
/*...name은 아래와 같다.
<input value=name.value onChange=name.onChange />
*/
<input {...name} />
)
}
const useTitle = initialTitle => {
const [title, setTitle] = useState(initialTitle);
const updateTitle = () => {
const htmlTitle = document.querySelector('title');
htmlTItle.innerText = title;
};
useEffect(updateTitle, [title]);
return setTitle;
}
const App = () => {
const titleUpdater = useTitle('Loading...');
setTimeout(() => titleUpdater("Home"), 5000);
}
const useClick = (onClick) => {
if (typeof onClick !== 'function') {
return;
};
const element = useRef();
useEffect(() => {
if (element.current){
element.current.addEventListener("click", onClick);
}
return () => {
element.current.removeEventListener('click', onClick);
}
}, []);
return element;
}
const App = () => {
const handleClick = () => console.log('hi');
const title = useClick(handleClick):
return (
<div className="App">
<h1 ref={title}>Title</h1>
</div>
);
}
useState
또는 useEffect
등 hooks들을 사용하지 않는 예제
const useConfirm = (callback, message="") => {
if (typeof callback !== 'function') {
return;
}
const confirmAction = () => {
if(confirm(message)){
callback();
}
}
return confirmAction;
}
const App = () => {
const consoleSure = () => console.log('sure!');
const handleClick = useConfirm(consoleSure, 'are you sure?');
return (
<div className="App">
<button onClick={handleClick}>Confirm</button>
</div>
);
}
const usePreventLeave = () => {
const listener = (event) => {
event.preventDefault();
}
const enablePrevent = () => {
window.addEventListener('beforeunload', listener);
}
const disablePrevent = () => {
window.removeEventListener('beforeunload', listener);
}
return { enablePrevent, disablePrevent };
}
const App = () => {
const {enablePrevent, disablePrevent} = usePreventLeave();
return (
<div className="App">
<button onClick={enablePrevent}>Protect</button>
<button onClick={disablePrevent}>UnProtect</button>
</div>
)
}