Custom Hooks

Jung taeWoong·2021년 7월 7일
1

React.js

목록 보기
16/19
post-thumbnail

Custom Hooks

  • 재사용 가능한 로직들을 함수로 뽑아내어 재사용성을 높힘
  • 여타 다른 hooks 처럼 접두사 use를 붙이는 것이 관례
  • custom Hooks은 다른 Hook을 호출하여 사용할수 있다.

※주의사항
너무 이른 단계에서 로직을 뽑아내려고 하지는 않는 게 좋습니다.
함수 컴포넌트가 할 수 있는 일이 더 다양해졌기 때문에 여러분의 코드에 있는 함수 컴포넌트의 길이도 길어졌을 것입니다.
이는 지극히 평범한 일이며 지금 바로 Hook으로 분리해야만 한다고 느낄 필요는 없습니다.
하지만 동시에 사용자 정의 Hook이 복잡한 로직을 단순한 인터페이스 속에 숨길 수 있도록 하거나 복잡하게 뒤엉킨 컴포넌트를 풀어내도록 돕는 경우들을 찾아내는 것을 권장합니다.

useState를 활용한 Custom Hoooks예제

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} />
    )
}

useEffect를 활용한 Custom Hooks예제

useTitle

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);
}

useClick

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>
  );
}

그 외 Custom Hooks

useState 또는 useEffect등 hooks들을 사용하지 않는 예제

useConfirm

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>
  );
}

usePreventLeave

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>
  )
}
profile
Front-End 😲

0개의 댓글