N.C 실전형 리액트 Hooks

김범·2022년 10월 16일
0
post-thumbnail

1. useState

1. useInput

import { useState } from "react"

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

사용법

const maxLen = value => !value.includes("@");
const name = useInput("Mr.", maxLen);

변수 선언 후 useInput(초깃값, 조건함수)

2. useTabs

import { useState } from "react";

export const useTabs = (initialTab, allTabs)=>{
    const [currentIndex, setCurrentIndex] = useState(initialTab);
    if(!allTabs || !Array.isArray(allTabs)){
        return;
    }
    return {
        currentItem: allTabs[currentIndex],
        changeItem: setCurrentIndex
    };
};

사용법

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"
    }
]

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>
    );
}
const {currentItem, changeItem} = useTabs(0, content);
변수 선언후 useTabs(초기인덱스,배열)

함수안에 changeItem(인덱스)으로 이벤트 실행시 변경될 탭을 지정할 수 있다.
currentItem을 이용해 지정된 탭의 내용을 뿌려줄 수 있다.

2. useEffect

1. useTitle

import { useEffect, useState } from "react"

export const useTitle = initialTitle => {
    const [title, setTitle] = useState(initialTitle);
    const updateTitle = ()=>{
        const htmlTitle = document.querySelector("title");
        htmlTitle.innerText = title;
    };
    useEffect(updateTitle, [title]);
    return setTitle;
}

사용법

const titleUpdater = useTitle("");
<div onClick={()=>{titleUpdater("타이틀명")}}>click</div>

변수에 useTitle()을 사용하여 onClick과 같은 액션시 변수의 매개변수로 변경할 타이틀 명을 넣어주어 사용한다.

2. useClick

import { useEffect, useRef } from "react";

export const useClick = (onClick)=>{
    const element = useRef();
    useEffect(()=>{
        if(typeof onClick !=="function"){
            return;
        }
        if(element.current){
            element.current.addEventListener("click", onClick);
        }
        return ()=>{
            if(element.current){
                element.current.removeEventListener("click", onClick);
            }
        }
    },[])
    return typeof onClick !== "function"? undefined: element;
}

사용법

const hello = useClick(()=>{console.log("say hello")})
<h1 ref={hello}>Hi</h1>
변수에 useClick 사용 후 적용할 요소에 ref에 변수명을 적어서 사용

3.useConfirm

export const useConfirm = (message="", onConfirm, onCancel) => {
    if(onConfirm && typeof onConfirm !== "function"){
      return;
    }
    if(onCancel && typeof onCancel !=="function"){
      return;
    }
    const confirmAction = ()=> {
      if(window.confirm(message)){
        onConfirm();
      }else {
        try{
          onCancel();
        } catch(error){
          return;
        }
      }
    }
    return confirmAction;
  }

사용법

const trueFunction = ()=>{console.log("확인입니다.")}
const falseFuntion = ()=>{console.log("취소입니다.)}
const confirmClick = useConfirm("질문",trueFunction,falseFunction)

변수에 useConfirm 사용 후 첫번째 매개변수로 질문, 두번째 매개변수로 true일 시 함수, 
세번째 매개변수로 false일 시 함수를 넣어준다.

4.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 };
  }

사용법

const {enablePrevent, disablePrevent} = usePreventLeave();
<button onClick={enablePrevent}>protect</button>
<button onClick={disablePrevent}>unprotect</button>

const {enablePrevent, disablePrevent} = usePreventLeave() 
선언 후 onClick이벤트에 같은 변수명으로 넣어준다

const {enablePrevent:변수명1, disablePrevent:변수명2} = usePreventLeave();
<button onClick={변수명1}>protect</button>
<button onClick={변수명2}>unprotect</button>
위와 같이 변수명을 변경하여 사용가능

5. useBeforeLeave

import { useEffect } from 'react';

export const useBeforeLeave = (onBefore)=>{
  useEffect(()=>{
    document.addEventListener("mouseleave", handle)
    return ()=> document.removeEventListener("mouseleave", handle)
  },[])
  if(typeof onBefore !=="function"){
    return; 
  }
  const handle = (event)=>{
    //마우스가 클라이언트Y가 0보다 작아질때 useBeforeLeave의 매개변수 onBefore을 실행
    const {clientY} = event;
    if(clientY <= 0){
      onBefore();
    }
  };
}

사용법

const useBeforeLeaveFunction = ()=> console.log("leaving");
useBeforeLeave(useBeforeLeaveFunction);

함수 생성 후 useBeforeLeave(함수명)으로 useBeforeLeave를 실행

6. useFadeIn

import { useEffect, useRef } from 'react';

export const useFadeIn = (duration = 1, delay = 0)=>{
    //매개변수에 듀레이션과 딜레이를 정할 수 있다
  const element = useRef();
  useEffect(()=>{
    if(element.current){
      const {current} = element;
      current.style.transition = `opacity ${duration}s ease-in-out ${delay}s`;
      current.style.opacity = 1;
    }
  })
  if(typeof duration !== "number" || typeof delay !== "number"){
    return
  }
  return {ref: element, style: {opacity:0}};
}

사용법

const fadeInH1 = useFadeIn();

변수를 지정하고 값에 useFadeIn()을 넣는다.
사용하고자 하는 요소에 전개연산자를 활용하여 변수를 넣어준다.
<h1 {...fadeInH1}>안녕하세요.</h1>

7. useNetwork

import { useEffect, useState } from 'react';

export const useNetwork = onChange => {
  const [status, setStatus] = useState(navigator.onLine);
  const handleChange = ()=>{
    if(typeof onChange === "function"){
      onChange(navigator.onLine);
    }
    setStatus(navigator.onLine);
  }
  useEffect(()=>{
    window.addEventListener("online", handleChange);
    window.addEventListener("offline", handleChange);

    return ()=>{
      window.removeEventListener("online", handleChange);
      window.removeEventListener("offline", handleChange);
    }
  },[])
  return status;
}

사용법

const onLine = useNetwork();
변수를 선언하고 값에 useNetwork()를 사용한다.

if(online){
     console.log("we just went online")
}else{
     console.log("we are offline")
}
useNetwork()의 매개변수에 useNetwork(handleNetworkChange)와같이 다른함수를 사용하여 
온라인일 경우 함수를 실행할 수 있다.

8. useScroll

import { useEffect, useState } from 'react';

export const useScroll = ()=>{
  const [state, setState] = useState({
    x:0,
    y:0
  });
  const onScroll = ()=>{
    //스크롤의 위치가 바뀔 때마다 state의 x와 y의 값을 변경
    setState({y: window.scrollY, x: window.scrollX})
    console.log("y ", window.scrollY, "x ", window.scrollX);
  }
  useEffect(()=>{
    window.addEventListener("scroll", onScroll);
    return ()=> window.removeEventListener("scroll", onScroll)
  },[])
  return state;
}

사용법

const {x,y} = useScroll();
위와 같이 변수 선언 후 

<h1 style={{color: y> 100 ? "red" : "blue"}}>HI</h1>
x혹은 y의 값에 따라 변경되는 조건문을 사용해준다.

9. useFullscreen

import { useRef } from 'react';

export const useFullscreen = (callback)=>{
  const element = useRef();
  const runCb = isFull => {
    if(callback && typeof callback === "function"){
      callback(isFull)
    }
  }
  const triggerFull = ()=>{
    if(element.current){
      if(element.current.requestFullscreen){
        element.current.requestFullscreen();
      }else if(element.current.mozRequestFullscreen){
        element.current.mozRequestFullScreen();
      }else if(element.current.webkitRequestFullscreen){
        element.current.webkitRequestFullscreen();
      }else if(element.current.msRequestFullscreen){
        element.current.msRequestFullscreen(); 
      }
      runCb(true);
    }
  }
  const exitFull = ()=>{
    document.exitFullscreen();
    if(element.current){
      if(element.current.requestFullscreen){
        element.current.requestFullscreen();
      }else if(element.current.mozRequestFullscreen){
        element.current.mozRequestFullScreen();
      }else if(element.current.webkitRequestFullscreen){
        element.current.webkitRequestFullscreen();
      }else if(element.current.msRequestFullscreen){
        element.current.msRequestFullscreen(); 
      }
      runCb(false);
    }
  }
  return {element, triggerFull, exitFull};
}

사용법

const onFullS = (isFull) => console.log(isFull ? "We are full" : "We are small");
const {element, triggerFull, exitFull} = useFullscreen(onFullS);

풀스크린을 할 대상에 ref={element}를 넣어주고 
온클릭이벤트로 풀스크린 버튼에 triggerFull을, 종료버튼에 exitFull을 넣어준다

10. useNotification

const useNotification = (title, options)=>{
    if(!("Notification" in window)){
      return;
    }
    const fireNotif = ()=>{
      if(Notification.permission !== "granted"){
        Notification.requestPermission().then(permission => {
          if(permission === "granted"){
            new Notification(title, options);
          }else {
            return;
          }
        });
      }else {
        new Notification(title, options);
      }
    };
    return fireNotif;
}

사용법

const triggerNotif = useNotification("Hello", {body:"Nice to meet you",requireInteraction:true})
<button onClick={triggerNotif}>button</button>

변수 선언 후 이벤트에 변수를 넣어사용한다
useNotification(타이틀명, {프로퍼티명:값}) 

notification API를 이용한 Hook
notification 관련 정보는 아래 링크에서 확인 가능

https://developer.mozilla.org/ko/docs/Web/API/notification

11. useAxios

import defaultAxios from "axios";
import { useEffect } from "react";
import { useState } from "react";

const useAxios = (opts, axiosInstance = defaultAxios)=>{
    const [state, setState] = useState({
        loading: true,
        error: null,
        data: null,
    });
    const [trigger, setTrigger] = useState(0);
    const refetch = ()=>{
        setState({
            ...state,
            loading: true
        });
        setTrigger(Date.now());
    }
    useEffect(()=>{
        axiosInstance(opts).then(data=>{
            setState({
                ...state,
                loading:false,
                data
            });
        }).catch(error=>{
            setState({...state, loading:false, error})
        })
    },[trigger])
    if(!opts.url){
        return;
    }
    return {...state, refetch};
}

export default useAxios;

사용법

const { loading, data, error, refetch } = useAxios({
url:"https://yts.mx/api/v2/list_movies.json"
});

위와같이 변수 선언 후 useAxios({url:주소})로 데이터를 받아온다

0개의 댓글