ReactHooks 배우기

Sammy·2022년 5월 30일
0

useInput

export const useInput = (initialValue, validator) => {
  const [value, setValue] = useState(initialValue);
  const onChange = (event) => {
    const {
      target: { value }
    } = event;
    let willUpdate = true;
    if (typeof validator === "function") {
      willUpdate = validator(value);
    }
    if (willUpdate) {
      setValue(value);
    }
  };
  return { value, onChange };
};
export default function App() {
  const maxLen = (value) => value.length <= 10;
  const name = useInput("Mr.", maxLen);
  return (
    <div className="App">
      <h1>Hello</h1>
      <input placeholder="Name" {...name} />
    </div>
  );
}

이름을 입력하는 input 태그 안에 글자가 10자를 넘는다면 maxLen은 false를 반환한다.
그럼 useInput에 onChange 안에 willUpdate는 false가 되고 setValue(value) 는 실행되지 않는다.
반대로 10자 이내라면 true를 반환해 setValue(value)가 실행되어 value에 내가 입력한 이름이 저장된다.

useTabs

export const content = [
  {
    tab: "Section 1",
    content: "I'm the content of the Section 1"
  },
  {
    tab: "Section 2",
    content: "I'm the content of the Section 2"
  }
];
const useTabs = (initialTab, allTabs) => {
  if (!allTabs || !Array.isArray(allTabs)) {
    return;
  }
  const [currentIndex, setCurrentIndex] = useState(initialTab);
  return {
    currentItem: allTabs[currentIndex],
    changeItem: setCurrentIndex
  };
};
export default function App() {
  const { currentItem, changeItem } = useTabs(0, content);
  return (
    <div className="App">
      {content.map((section, index) => (
        <button onClick={() => changeItem(index)}>{section.tab}</button>
      ))}
      <div>{currentItem.content}</div>
    </div>
  );
}

content를 map을 이용해서 content.tab을 button형태로 보여지게 한다.
화면에는 'tab'인 Section 1과 Section 2 버튼이 렌더링된다.
그 다음 버튼이 클릭될 때 해당되는 tab의 'content'가 나오도록 하기위해
클릭할 때 map의 index를 changeItem으로 전달해주고
changeItem를 setCurrentIndex에 삽입해 currentIndex의 값을 변경해준다.

useClick

export const useClick = (onClick) => {
  if (typeof onClick !== "function") {
    return;
  }
  const element = useRef();
  useEffect(() => {
    if (element.current) {
      element.current.addEventListener("click", onClick);
    }
    return () => {
      if (element.current) {
        element.current.removeEventListener("click", onClick);
      }
    };
  }, []);
  return element;
};
export default function App() {
  const sayHello = () => console.log("say Hello");
  const title = useClick(sayHello);
  return (
    <div className="App">
      <h2 ref={title}>hello</h2>
    </div>
  );

component가 mount될 때 onClick의 click 이벤트가 실행되고
componentWillUnmount 상태일 때 onClick의 click이벤트를 제거한다.

useConfirm

export const useConfirm = (message = "", onConfirm, onCancel) => {
  if (!onConfirm || typeof onConfirm !== "function") {
    return;
  }
  if (onCancel && typeof onCancel !== "function") {
    return;
  }
  const confirmAction = () => {
    if (confirm(message)) {
      onConfirm();
    } else {
      onCancel();
    }
  };
  return confirmAction;
};
export default function App() {
  const deleteWorld = () => console.log("Deleting the world...");
  const abort = () => console.log("Aborted");
  const confirmDelete = useConfirm("Are you sure? ", deleteWorld, abort);
  return (
    <div className="App">
      <button onClick={confirmDelete}>Delete the world</button>
    </div>
  );
}

button을 누르면 Are you sure? 이라는 confirm창이 뜬다.
거기서 취소(false)를 누르면 abort(onCancle)가 실행이 되고
확인(true)를 누르면 deleteWorld(onConfirm)가 실행된다.

usePreventLeave

export const usePreventLeave = () => {
  const listener = (event) => {
    event.preventDefault();
    event.returnValue = "";
  };
  const enablePrevent = () => {
    window.addEventListener("beforeunload", listener);
  };
  const disablePrevent = () => {
    window.removeEventListener("beforeunload", listener);
  };
  return { enablePrevent, disablePrevent };
};
export default function App() {
  const { enablePrevent, disablePrevent } = usePreventLeave();
  return (
    <div className="App">
      <button onClick={enablePrevent}>protect</button>
      <button onClick={disablePrevent}>unprotect</button>
    </div>
  );
}

"beforeunload" 이벤트를 사용하면 사용자가 페이지를 떠날 때 정말로 떠날 것인지 묻는 확인 대화 상자를 표시할 수 있습니다. 사용자가 확인을 누를 경우 브라우저는 새로운 페이지로 탐색하고, 취소할 경우 탐색을 취소하고 현재 페이지에 머무릅니다.
protect 버튼을 클릭하면 enablePrevent 함수가 실행되어 "breforeunload" 이벤트가 실행됩니다.
unprotect 버튼을 클릭하면 disablePrevent 함수가 실행되어 "breforeunload" 이벤트가 제거됩니다.

useBeforeLeave

export const useBeforeLeave = (onBefore) => {
  if (typeof onBefore !== "function") {
    return;
  }
  const handle = (event) => {
    const { clientY } = event;
    if (clientY <= 0) { //마우스가 화면밖 위로 올라갈때만
      onBefore();
    }
  };
  useEffect(() => {
    document.addEventListener("mouseleave", handle);
    return () => document.removeEventListener("mouseleave", handle);
  }, []);
};
export default function App() {
  const begForLife = () => console.log("pls don't leave");
  useBeforeLeave(begForLife);
  return (
    <div className="App">
      <h2>Hello</h2>
    </div>
  );
}

"mouseleave" 이벤트는 지정한 위치에서 마우스가 벗어날 때 함수를 실행하는 eventListener입니다.
useBeforeLeave함수에 begForLife인자("pls don't leave"출력) 를 넘겨주었고 만약 마우스가 화면 밖 위로 벗어날 때만 onBefore이 실행됩니다.

profile
Web Developer

0개의 댓글