기억의 실마리
2022. 11. 16. 19:59

# useAxios의 기능

기능은 fetch와 유사하고 간단하게 사용할땐 fetch를,

확장성을 염두해봤을 땐 axios를 쓰는게 좋다.

fetch와 다르게 인스턴스를 사용할 수 있는 장점도 있다.

(두번째인자에 넣지 않을경우 기본값으로 설정된다.)

 

import defaultAxios from "axios";
//터미널에 npm i axios 하여 인스톨한 후 임포트해준다.

import { useEffect, useState } from "react";

const useAxios = (opts, axiosInstance = defaultAxios) => {
    //opts 는 api를 등록할 수 있다. fetch와 다르게 바로 json화 되는게 axios의 장점이다.
    //두번째 인자 axiosInstance는 인스턴스이고 아무것도 넣지않으면 기본값으로 적용

    const [state, setState] = useState({
        loading: true,
        error: null,
        data: null
    });
    //로딩, 에러, 데이터를 사용할 것이기 때문에 각각의 key와 value의 디폴트를 설정해준다.
    
    const [trigger, setTrigger] = useState(0);
    if (!opts.url) {  //유효성을 검사한다. 기본적으로 opts(API)는 url이기 때문
        return;
    }
    const refetch = () => {
        setState({
            ...state,
            loading: true
        });
        setTrigger(Date.now());
    };
    /* 리패치를 위한 함수이며 함수 실행시 setTrigger로 인해서 
    함수가 실행될 때마다 trigger는 계속해서 다른 값을 반환한다.
    이 후에 useEffect의 deps로 넣기 위한 트리거다.( 리패치 해야되니까 ) */


    useEffect(() => {
        axiosInstance(opts)       //fetch와 같은 기능을 해주고
            .then((data) => {     //로딩이되면(then) setState를 통해서 state값이 바뀐다.
                setState({
                    ...state,
                    loading: false,
                    data
                });
            })
            .catch((error) => {
                setState({ ...state, loading: false, error });
                //catch 는 에러를 캣치하며, reject상태일경우 내부 메소드를 실행한다.
                });
    }, [trigger]);
    //트리거가 deps에 들어가 있으니 trigger가 바뀌면 re-render한다.
    
    return { ...state, refetch };
    //반환값은 state의 모든 리터럴과 refetch함수이다.
};

 

# 사용예시

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

  return (
    <div className="App" style={{ height: "1000vh" }}>
      <h1>{data && data.status}</h1>
      <h2>{loading && "Loading"}</h2>
      <button onClick={refetch}>Refetch</button>
    </div>
  );

useAxios에서 opts를 { url: " 주소 " } 오브젝트로 전달해주었고

data가 있으면(API를 정상적으로 받아오면) data.status가 h1에 마운트되도록 만들었다.

로딩이 true일 경우에만 Loading이라는 문자열을 h2에 마운트하고

Refetch버튼을 누르면 refetch함수를 통해서 새로고침된다.

'Frontend > React-Hooks' 카테고리의 다른 글

[ React Hook ] 9. useNotification  (0) 2022.11.12
[ React Hook ] 8. useFullscreen  (0) 2022.11.09
[ React Hook ] 7. useFadeIn  (0) 2022.11.05
[ React Hook ] 6. useScroll  (0) 2022.11.04
[ React Hook ] 5. useNetwork  (0) 2022.11.03
2022. 11. 12. 20:39

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

useNotification은 알림기능을 사용할때 쓰는 hook이다.

 

반환값은 fireNotif를 반환한다.

 

fireNotif는 운영체제 내에서 알림설정이 허용 되었을때만 실행된다.

 

useNotification의 첫번째 인자는 알림의 타이틀을 전달받고

 

두번째 인자는 옵션으로, Notification의 API웹사이트에서 확인해 볼 수 있다.

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

( 사용예시로는 { body: "적고싶은 내용" } 옵션을 사용할 예정이다. )

 

 

# 설명

 

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;

권한이 허용되지 않았을때 권한획득을 요청한다.

 

Notification.requestPermission().then() 은 권한을 획득하기 위한 구문이다.

 

이 후 권한이 허용 되었다면 new Notification(title, options)를 통해서 알림을 띄우고

 

허용하지 않게되면 return하여 브레이크를 건다.

 

애초에 허용되어있다면 바로 알림을 띄운다.

 

 

# 사용예시

 

const triggerNotif = useNotification("Can I steal your kimch?", {
   body: "I love kimch dont you"
});

 <button onClick={triggerNotif}>hello</button>

triggerNotif변수를 선언해서 useNotification을 할당해주고 매게변수에 각각 타이틀과 옵션을 넣어준다.

 

이 후 버튼요소에 onClick이벤트를 넣어주고 triggerNotif를 할당해주어서 클릭시 Notification기능을 실행시킨다.

'Frontend > React-Hooks' 카테고리의 다른 글

[ React Hook ] 10. useAxios  (0) 2022.11.16
[ React Hook ] 8. useFullscreen  (0) 2022.11.09
[ React Hook ] 7. useFadeIn  (0) 2022.11.05
[ React Hook ] 6. useScroll  (0) 2022.11.04
[ React Hook ] 5. useNetwork  (0) 2022.11.03
2022. 11. 9. 22:48

# useFullscreen의 기능

 

import {useRef} from "react";

export const useFullscreen = (callback) => {
    const element = useRef();
    const runCd = (isFull) => {
        if (callback && typeof callback === "function") {
            callback(isFull);
        }
    };
    const triggerFull = () => {
        const El_Curt = element.current;
        if (El_Curt) {
            if (El_Curt.requestFullscreen) {
                El_Curt.requestFullscreen();
            } else if (El_Curt.MozRequestFullscreen) {
                El_Curt.MozRequestFullscreen();
            } else if (El_Curt.webkitRequestFullscreen) {
                El_Curt.webkitRequestFullscreen();
            } else if (El_Curt.msRequestFullscreen) {
                El_Curt.msRequestFullscreen();
            }
            runCd(true);
        }
    };
    const exitFull = () => {
        if (document.exitFullscreen) {
            document.exitFullscreen();
        } else if (document.MozCancelFullscreen) {
            document.MozCancelFullscreen();
        } else if (document.webkitExitFullscreen) {
            document.webkitExitFullscreen();
        } else if (document.msExitFullscreen) {
            document.msExitFullscreen();
        }
        runCd(false);
    };
    return { element, triggerFull, exitFull };
};

useFullscreen은 등록한 이미지를 전체화면모드로 전환할 수 있도록 이벤트를 추가해주는 hook이다.

 

반환값은 { element, triggerFull, exitFull }를 반환한다.

 

triggerFull은 전체화면 이벤트를 추가해주는 함수이고

 

exitFull는 전체화면이벤트를 취소해주는 기능을 가진 함수이다.

 

element는 useFullscreen을 사용할 컴포넌트요소에 ref 속성으로 접근하기 위한 값이다.(useRef를 사용한 이유)

 

 

# 설명

 

const element = useRef();

element라는 변수는 컴포넌트에 ref속성으로 접근하기 위해서 useRef를 사용하여 반환값으로 둔다.

 

 

const runCd = (isFull) => {
    if (callback && typeof callback === "function") {
        callback(isFull);
    }
};

 

useFullscreen의 매개변수가 true(존재하고)이고 코드의 타입이 함수인경우,

 

useFullscreen의 매개변수로 들어간 함수(callback)의 매개변수가 runCd의 매게변수로 전달된다는 뜻이다.

 

------------------------------------------------------------------

< 간단한 예시 >

 

const Hi = (event) => { console.log( event ? "Hi" : "I can't say Hi" ) };

 

... useFullscreen(Hi);

 

runCd(true);

 

결과로는 runCd의 매개변수는 true이므로  useFullscreen의 매개변수로 들어간 Hi함수의 매개변수

event는 트루값을 전달받게 되므로 콘솔로그는 "HI" 가 반환된다.

-----------------------------------------------------------------

 

 

const triggerFull = () => {
    const El_Curt = element.current;
    if (El_Curt) {
        if (El_Curt.requestFullscreen) {
            El_Curt.requestFullscreen();
        } else if (El_Curt.MozRequestFullscreen) {
            El_Curt.MozRequestFullscreen();
        } else if (El_Curt.webkitRequestFullscreen) {
            El_Curt.webkitRequestFullscreen();
        } else if (El_Curt.msRequestFullscreen) {
            El_Curt.msRequestFullscreen();
        }
        runCd(true);
    }
};

triggerFull함수는 useRef를 사용해서 current리터럴이 포함되어있는 겨우에 풀스크린 이벤트를 추가해주는 함수이다.

 

El_curt는 ( element.current )를 반복하기 싫기 때문에 변수로 만들어 준 이후 사용한다.

 

else if 를 이용하여 비슷하지만 다른 이벤트를 추가해준 이유는 웹브라우저마다 반응하는 이벤트이름이 다르기 때문이다.

 

Firefox = moz

Opera = webkit

Microsoft (Edge)  =  ms

 

위와 같이 웹브라우저 마다 다를 경우를 대비하여, 추가적으로 조건문을 사용하여 이벤트명을 다양하게 입력해준다.

 

 

const exitFull = () => {
    if (document.exitFullscreen) {
        document.exitFullscreen();
    } else if (document.MozCancelFullscreen) {
        document.MozCancelFullscreen();
    } else if (document.webkitExitFullscreen) {
        document.webkitExitFullscreen();
    } else if (document.msExitFullscreen) {
        document.msExitFullscreen();
    }
    runCd(false);
};

exitFull함수는 triggerFull함수와 반대로 천제화면을 해제하는 이벤트이다.

 

triggerFull함수와 동일하게 웹브라우저마다 적용될 수 있도록 웹사이트에 맞는 각각의 추가적으로 조건문을 만들어준다.

 

 

# 사용예시

 

const onFullS = (isFull) => {
  console.log(isFull ? "We are Full" : "We are Small");
};

const { element, triggerFull, exitFull } = useFullscreen(onFullS);

<div className="App" style={{ height: "1000vh" }}>
    <div ref={element}>
        <img
            src="https://p4.wallpaperbetter.com/wallpaper/817/916/889/falcon-9-rocket-4k-high-definition-wallpaper-preview.jpg"
            alt="Picture"
        />
        <button onClick={exitFull}>Exit fullscreen</button>
    </div>
    <button onClick={triggerFull}>Make fullscreen</button>
</div>

onFulls는 전체화면이 활성화, 비활성화되었을 때  runCd를 통해서 매개변수에 true와 false를 전달받기때문에

 

onFulls의 매개변수isFull을 넣어서 조건문을 만들어준다.

 

구조분해할당을 사용하여서 useFullscreen의 반환값인 element, triggerFull, exitFull을 가져와서 컴포넌트에 넣어준다.

 

전체화면 이벤트를 실행시킬 컴포넌트요소 속성에 ref={element} 를 넣어서 이벤트를 실행할 수 있는 상태로 만들어준다.

 

이후 버튼에 각각 exitFull함수와 triggerFull함수를 넣어줘서 활성화, 비활성화 할 수 있는 버튼을 만들어준다.

( exitFull버튼은 ref-{elemet} 요소 안에 자식요소로 존재함으로 전체화면 상태일때도 img요소 밑에 존재한다. )

'Frontend > React-Hooks' 카테고리의 다른 글

[ React Hook ] 10. useAxios  (0) 2022.11.16
[ React Hook ] 9. useNotification  (0) 2022.11.12
[ React Hook ] 7. useFadeIn  (0) 2022.11.05
[ React Hook ] 6. useScroll  (0) 2022.11.04
[ React Hook ] 5. useNetwork  (0) 2022.11.03
2022. 11. 5. 22:06

# useFadeIn의 기능

 

import {useEffect, useRef} from "react";

export const useFadeIn = (duration = 1, delay = 0) => {
    if (typeof duration !== "number" || typeof delay !== "number") {
        return;
    }

    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;
        }
    }, []);
    return { ref: element, style: { opacity: 0 } };
};

useFadeIn은 opacity를 사용하여 서서히 나타나는 기능을 사용할때 쓰는 hook이다.


반환값은 { ref: element, style: { opacity: 0 } } 을 반환한다.

 

즉 style.opacity를 통해서 투명도에 접근할 수 있게 만들어 준다.

 

 

# 설명

 

if (typeof duration !== "number" || typeof delay !== "number") {
    return;
}

우선 가장먼저 첫번째 전달인자(duration)와 두번째 전달인자(delay)가 숫자인지 확인하여 유효성 검사를 한다.

 

 

const element = useRef();

이 후에 element라는 변수를 선언해주고 useRef()를 할당해주고 임포트 시켜준다.( import {useRef} from "react" )

 

useRef로 인해 element는 ref(refenrence)속성으로 접근 가능하게 된다.

ex) <div ref={element} > hi </div>

 

그리고 useRef가 할당된 변수에는 current라는 속성이 추가되고, 이는 할당된 변수의 속성 전체를 감싸는 속성이 된다.

 

 

	useEffect(() => {
        if (element.current) {
            const { current } = element;
            current.style.transition = `opacity ${duration}s ease-in-out ${delay}s`;
            current.style.opacity = 1;
        }
    }, []);
    return { ref: element, style: { opacity: 0 } };

useEffect를 사용해서 ( element.current )가 true일때 = ( useRef가 할당된 변수일때 ) 함수를 실행하도록 만든다.

 

구조분해할당을 사용하여 element에서 current 속성을 가져온 후에 스타일에 접근하여

 

transition과 opacity를 변경할 수 있도록 구성해준다.

 

useFadeIn의 반환값은 ref: element , style: { opacity: 0 } 의 속성을 반환한다.

 

 

# 사용예시

 

 const fadeInH1 = useFadeIn(1, 2);
 const fadeInP = useFadeIn(5, 10);

 <h1 {...fadeInH1}>hello</h1>
 <p {...fadeInP}>holly sheet</p>

fadeInH1과 fadeInP를 선언해서 각각 h1,p 시멘틱테그에 적용할 수 있도록 만들어 준다.

 

useFadeIn의 첫번째 전달인자는 duration이고 두번째 전달인자는 delay이다.

 

속성(attribute)에 보면 { ...변수명 } 으로 해준 부분은 결과적으로 변수에 할당된 값을 적용(가져온다)시킨다는 뜻이다.

 

그렇게 되면 useFadeIn의 반환값인 { ref: element, style: { opacity: 0 } }를 가져오게 되고

 

각 전달인자에서 받은 값들이 적용된 결과를 보여주게 된다.

'Frontend > React-Hooks' 카테고리의 다른 글

[ React Hook ] 9. useNotification  (0) 2022.11.12
[ React Hook ] 8. useFullscreen  (0) 2022.11.09
[ React Hook ] 6. useScroll  (0) 2022.11.04
[ React Hook ] 5. useNetwork  (0) 2022.11.03
[ React Hook ] 4. usePreventLeave  (0) 2022.11.02
2022. 11. 4. 22:15

# useScroll의 기능

 

import {useEffect, useState} from "react";

export const useScroll = () => {
    const [state, setState] = useState({
        x: 0,
        y: 0
    });
    const onScroll = () => {
        setState({ y: window.scrollY, x: window.screenX });
    };
    useEffect(() => {
        window.addEventListener("scroll", onScroll);
        return () => window.removeEventListener("scroll", onScroll);
    }, []);
    return state;
};

useScroll은 스크롤의 위치를 감지하여 확인할 수 있는 hook이다.


반환값은 { x : 0(위치) , y : 0(위치) }로 각 스크롤의 x와 y값을 반환한다.

 

 

# 설명

 

const [state, setState] = useState({
    x: 0,
    y: 0
});

 

useState를 사용해서 객체리터럴 x와 y를 만들고 x에는 x좌표의 스크롤위치와

 

y에는 y좌표 스크롤 위치를 불러올 것이다.

 

 

const onScroll = () => {
    setState({ y: window.scrollY, x: window.screenX });
};

onScroll함수를 만들어주고 setState에 y = y스크롤위치, x = x스크롤위치를 넣어주는 기능을 넣어준다.

 

 

useEffect(() => {
    window.addEventListener("scroll", onScroll);
    return () => window.removeEventListener("scroll", onScroll);
}, []);
return state;

useEffect를 사용하여 이벤트 리스너를 걸어준다.

 

window에서 스크롤되면 onScroll함수를 실행시킨다.

 

스크롤이 될때마다 onScroll가 실행되고 onScroll 내부에서는 setState를 변환시켜주기 때문에

 

state의 값을 계속해서 re-render를 시켜준다.

 

그리고 컴포넌트가 보이지 않을때는 이벤트를 삭제 해준다.

 

 

# 사용예시

 

 const { y } = useScroll();

 <div className="App" style={{ height: "1000vh" }}>
     <h1 style={{ position: "fixed", color: y > 100 ? "red" : "blue" }}>hi</h1>
 </div>

구조분해할당을 사용하여 useScroll에서 y를 가져온다.

 

이 후에 style.color에 y가 100보다 크면 "red" 색상이 되고, 적으면 "blue"색상이 되도록 만들었다.

 

결과 : 스크롤을 내리면 red가 되고 가장위로 올리면 blue가 된다.

'Frontend > React-Hooks' 카테고리의 다른 글

[ React Hook ] 8. useFullscreen  (0) 2022.11.09
[ React Hook ] 7. useFadeIn  (0) 2022.11.05
[ React Hook ] 5. useNetwork  (0) 2022.11.03
[ React Hook ] 4. usePreventLeave  (0) 2022.11.02
[ React Hook ] 3. useTabs  (0) 2022.10.31
2022. 11. 3. 21:45

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

useNetwork는 네트워크의 상태가 온라인인지 오프라인인지 확인할 수 있는 hook이다.


반환값은 boolean형이다. ( true = online && false = offline )

 

 

# 설명

 

const [status, setStatus] = useState(navigator.onLine);

useState의 디폴트값은 navigator.onLine 이다.

 

navigator는 브라우저에 대한 버전, 정보, 종류 등 여러속성을 가져올 수 있다.

 

이 후에 onLine으로 접근을 했기 때문에 onLine이면 ture, offLine이면 false를 반환한다.

 

 

const handleChange = () => {
    if (typeof onChange === "function") {    //onChange는 useNetwork의 Argument이다.
        onChange(navigator.onLine);
    }
    setStatus(navigator.onLine);
};

handleChange 함수를 만들어주고, 내용은 useNetwork의 Argument인 onChange가 함수일때

 

함수를 실행할 수 있도록 유효성검사를 거친 후에

 

setStatus함수를 통해서 status를 re-render 시켜주는 기능이다.

 

 

useEffect(() => {
    window.addEventListener("online", handleChange);
    window.addEventListener("offline", handleChange);

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

return status; // useNetwork의 return값.

useEffect를 사용하여 window에 ( on / offLine 이벤트 )를 걸어주고 실행시킬 함수는 handleChange로 넣어준다.

 

컴포넌트가 실행되지 않을땐 이벤트를 삭제해주는 함수를 넣는다.

 

이 후 re-render된 status를 반환한다(true or false).

 

 

# 사용예시

 

 const handleNetworkChange = online => {
   console.log(online ? "We just went online" : "We are offline");
 };
 const onLine = useNetwork(handleNetworkChange);

 <h1>{onLine ? "Online" : "Offline"}</h1>

handleNetworkChange라는 새로운 변수를 만들어주고 해당속성에 직접 접근하기 위해서

 

매게변수 online 을 넣어준 후 콘솔로그를 만들어서 true일때와 false일때 반응하는 기능을 각각 넣어준다.

 

이 후에 onLine 이라는 새로운 변수를 만들고 useNetwork를 사용하고

 

전달인자에 handleNetworkChange함수를 넣어준다.

 

이렇게 되면 useNetwork는 status를 반환하고,

 

status는 boolean형으로 값을 반환하기 때문에

 

콘솔로그가 online일땐( true ) "We just went online" ,

 

offline일땐( false ) "We are offline" 로 찍히게 된다.

'Frontend > React-Hooks' 카테고리의 다른 글

[ React Hook ] 7. useFadeIn  (0) 2022.11.05
[ React Hook ] 6. useScroll  (0) 2022.11.04
[ React Hook ] 4. usePreventLeave  (0) 2022.11.02
[ React Hook ] 3. useTabs  (0) 2022.10.31
[ React Hook ] 2. useTitle  (0) 2022.10.30
2022. 11. 2. 20:07

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

usePreventLeave는 웹사이트를 나가려고 할 때 알람문구를 띄워 한번 더 묻는 기능이 필요할때 사용한다.

 

useState나 useEffect를 사용하지 않은 순수함수로 만든 hook이다.

 

 

# 설명

 

const listener = (event) => {
        event.preventDefault();
        event.returnValue = "";
    };

우선 리스너 함수를 만든 후 기본옵션을 막아준다.

 

전달인자로부터 returnValue = ""; 를 해준다. 만약 이 작업을  하지않는다면,

 

이 후에 사용될 이벤트인 " beforeunload " 가 실행되지 않는다. 

 

 

const enablePrevent = () =>
    window.addEventListener("beforeunload", listener); //이벤트 추가
const disablePrevent = () =>
    window.removeEventListener("beforeunload", listener); //이벤트 삭제

이 후 이벤트 추가 함수와(enablePrevent), 삭제 함수(disablePrevent)를 만들어준다.

 

beforeunload 가 되면 listener함수를 실행하도록 만들면 된다.

# 사용예시

 

	const usePreventLeave = () => {
    
    	... // (내용 생략)
        
        return { enablePrevent, disablePrevent };
    };
    
    const {enablePrevent, disablePrevent} = usePreventLeave();
    
	<button onClick={enablePrevent}/>
    <button onClick={disablePrevent}/>

usePreventLeave는 enablePrevent와 disablePrevent를 반환하고

 

사용할때는 간단하게 사용하기 위해서 구조분해할당을 사용한다.

 

<button onClick={enablePrevent}/> 를 클릭하면 이벤트가 실행돼서 alert처럼 알람문구가 뜨게되고

 

취소를 누르면 웹사이트를 유지, 승인을 누르면 웹사이트를 나간다.

 

반대로 <button onClick={enablePrevent}/> 를 누른 후에 <button onClick={disablePrevent}/> 를 누르면

 

추가되었던 이벤트가 취소되기 때문에 웹사이트를 나가면 알람문구가 뜨지않고 바로 나가진다.

'Frontend > React-Hooks' 카테고리의 다른 글

[ React Hook ] 6. useScroll  (0) 2022.11.04
[ React Hook ] 5. useNetwork  (0) 2022.11.03
[ React Hook ] 3. useTabs  (0) 2022.10.31
[ React Hook ] 2. useTitle  (0) 2022.10.30
[ React Hook ] 1. useInput  (0) 2022.10.30
2022. 10. 31. 23:10

 

# useTabs의 기능

 

import {useState} from "react";

export const useTabs = (initialTab, allTabs) => {
    if (!allTabs || !Array.isArray(allTabs)) {
        return;
    }

    const [currentIndex, setCurrentIndex] = useState(initialTab);
    return {
        currentItem: allTabs[currentIndex],
        changeItem: setCurrentIndex
    };
}

 

useTabs는 배열이나 객체의 값을 useState의 별도사용 없이 re-render시켜주는 hook이다.

 

사용법 :  useTabs를 새로운 변수에 할당하고 컴포넌트에 넣어서 사용한다.

 

 

# 예시

 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 {currentItem, changeItem} = useTabs(1, content);
 <div className="App">
      {content.map((section, index) => (
        <button onClick={ ()=> changeItem(index) }>{section.tab}</button>
      ))}
      <div>{currentItem.content}</div>
 </div>

위와 같이 예시로 content 라는 배열내에 객체 리터럴을 반환하는 변수가 있다.

 

그리고 구조분해할당을 사용하여 useTabs에서 반환값인 currentItem 와 changeItem를 가져와서

 

컴포넌트 내부에 넣어서 사용할 수 있다.

 

 

# 설명

import {useState} from "react";

export const useTabs = (initialTab, allTabs) => {
    if (!allTabs || !Array.isArray(allTabs)) {
        return;
    }

    const [currentIndex, setCurrentIndex] = useState(initialTab);
    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"
    }
 ]

 const {currentItem, changeItem} = useTabs(1, content);
 <div className="App">
      {content.map((section, index) => (
        <button onClick={ ()=> changeItem(index) }>{section.tab}</button>
      ))}
      <div>{currentItem.content}</div>
 </div>

useTabs의 구조와 예시는 이러하고

 

 

const useTabs = (initialTab, allTabs)

첫번째 전달인자(argument)는 초기에 default 로 render될 리터럴을 넣는다.

 

지금 예시는 배열형태이기 때문에 숫자를 넣어주면 된다. (예시를 기준으로 [ 0, 1 ] 이있다.)

 

그리고 두번째 전달인자는 정보를 가져올 배열의 변수를 넣어준다. ( content )

 

 

    if (!allTabs || !Array.isArray(allTabs)) {
        return;
    }

if문으로 allTabs가 false이거나 Array가 아닌경우에는 실행되지 않도록 브레이크를 걸어준다.

 

 

const [currentIndex, setCurrentIndex] = useState(initialTab);

이 후에 useState를 이용하여 useTabs에서 받아온 첫번째 전달인자인 initialTab을 default로 두고

 

re-render될 수 있는 상태가 되도록 만든다.

 

 

    return {
        currentItem: allTabs[currentIndex],
        changeItem: setCurrentIndex
    };

그리고 useTabs의 반환값은 위와 같다.

 

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

정보를 가져올 배열 content이다.

 

 const {currentItem, changeItem} = useTabs(1, content);
 <div className="App">
      {content.map((section, index) => (
        <button onClick={ ()=> changeItem(index) }>{section.tab}</button>
      ))}
      <div>{currentItem.content}</div>
 </div>

useTabs에서 반환값인 currentItem과  changeItem을 꺼낸다 ( 구조분해할당 )

 

currentItem = 배열전체 [  렌더링함수로인해서 바뀐 렌더링 벨류  ]
changeItem = 렌더링함수()

 

이렇게 이해를 하고 있어야  더 쉽다.

 

# 컴포넌트 적용예시

      {content.map((section, index) => (
        <button onClick={ ()=> changeItem(index) }>{section.tab}</button>
      ))}

# .map

배열 content에서 .map 을 사용해서 모든 배열에 각각 함수를 만들어서 반환하게 만들어준다.(forEach와 같은구조)

 

section이라는 첫번째 매게변수를 만들고( content로 접근할 수 있는 매게변수 )

 

두번째 매게변수는 index로 .map에서 기본으로 제공하는 기능으로

 

배열의 순서대로 { index : 순서 } 의 속성이 들어간다. content는 0, 1이 있으니

 

0번째 배열에는 { index: 0 }, 1번째 배열에는 { index: 1 } 이라는 속성이 만들어지고

 

{ index: 0 }을가진 버튼 하나와 { index: 1 }을 가진 버튼, 총 2개의 버튼을 만든다.

 

# - button onClick -

버튼에 온클릭 이벤트를 만들어주고 내용은 changeItem(index) 이다.

 

 changeItem = 렌더링함수() 이기때문에  setCurrentIndex( index ) 가 된다.

 

그렇게 되면 currentIndex는 전달받은 index로 re-render되고

 

currentItem : allTabs[ currentIndex ] 이므로 

 

currentItem은 클릭했을때 해당 index에 일치하는 배열순서의 객체리터럴(값)을 가져온다.

( 배열전체 [  렌더링함수로인해서 바뀐 렌더링 벨류  ] )

 

 

# 컴포넌트 내용

 	content.map((section, index) => { ... } )

내용은  {section.tab}  이다.

 

section은 단순하게 함수가 적용된 해당요소에 접근하기 위한 매게변수이기때문에

 

{section.tab} = {conent.tab}  과 같다. 즉 버튼의 내용은 각 index에 맞게 tab(key)의 value로 나타난다.

(Section 1)   (Section 2)      < == 이런 버튼이 나온다.

 

<div>{currentItem.content}</div>

위에서 말했던

 

------------------------------------------------------------------------------------------------

 

currentItem : allTabs[ currentIndex ] 이므로 

 

currentItem은 클릭했을때 해당 index에 일치하는 배열순서의 객체리터럴(값)을 가져온다.

( 배열전체 [  렌더링함수로인해서 바뀐 렌더링 벨류  ] )

 

 -----------------------------------------------------------------------------------------------

이 부분이고

 

{클릭한 녀석의 객체리터럴}.content 이므로 

 

위에 버튼 (Section 1) 을 클릭하면

I'm the content of the Section 1

 

위에 버튼 (Section 2) 을 클릭하면

I'm the content of the Section 2

 

이렇게 내용을 보여준다.

'Frontend > React-Hooks' 카테고리의 다른 글

[ React Hook ] 6. useScroll  (0) 2022.11.04
[ React Hook ] 5. useNetwork  (0) 2022.11.03
[ React Hook ] 4. usePreventLeave  (0) 2022.11.02
[ React Hook ] 2. useTitle  (0) 2022.10.30
[ React Hook ] 1. useInput  (0) 2022.10.30