이것저것

[Hook]노마드 코더로 hook 공부하기 (3) 본문

React를 파고파고/Hook

[Hook]노마드 코더로 hook 공부하기 (3)

곰태태 2020. 6. 28. 21:51
반응형
SMALL

useBeforeLeave

탭을 닫을때 실행되는 function이다.

마우스가 창을 벗어나면 alert창을 실행시킬수도 있다.

 

useEffect를 사용하기 때문에 addEvent를 생성해줬으므로 return값에는 removeEvent를 정의해준다.

dependency는 [ ]로 빈값을 주어서 update 되었을때도 addEvent가 작동하도록한다.(여기서는 update 될일은 없다.)

handle에서 event를 출력해주니 마우스가 browser의 위로 올라갈때 clientY가 0보다 작아지는 것을 확인했다.

그래서 창위로 올라갔을때 onBefore를 출력하도록 하였다.

event로 clientY가 0보다 작을때의 조건을 넣어주었다.

이것을 응용해서 alert창으로 onBefore를 출력하도록 하는 방법도 있을것이다.

import React, { useEffect } from 'react';
import ReactDOM from 'react-dom';
import './index.css';

const useBeforeLeave = (onBefore) => {
  /*
  const handle = () => {
    // console.log("leaveing");   //마우스가 벗어났을때 leaving을 콘솔출력
    onBefore();   //마우스가 벗어났을때 Pls don't leave를 콘솔출력
  };
  */
  const handle = (event) => {
  	console.log(event);
    const {clientY} = event;
    if(clientY <= 0){
      onBefore();   //마우스가 위로 벗어날때만 onBefore를 출력
    }
  };

  useEffect(() => {
    document.addEventListener("mouseleave", handle)
    return () => document.removeEventListener("mouseleave", handle)
  }, []);
};

const App = () => {
  const begForLife = () => console.log("Pls don't leave");
  useBeforeLeave(begForLife);
  return(
    <div className="App">
      <h1>Hello</h1>
    </div>
  )
};

ReactDOM.render(<App />, document.getElementById('root'));

useFadeIn & useNetwork

1) useFadeIn

서서히 나타나거나 서서히 사라지게하는 animation을 넣을 수 있다.

 

opacity는 duration 초 만큼 천천히 나타나거나 사라지고

ease-in-out은 delay 초 만큼 기다렸다가 나타난다.

opacity는 1일때 나타나고 0일때 사라진다.

그러므로 처음에는 0이었다가 current.style.opacity를 1로 해주었으므로 서서히 나타나게된다.

서서히 없어지게 하고 싶다면 return의 opacity를 1로 current.style.opacity를 0으로 바꿔주면된다.

fadeInH1과 fadeInp는 하나만 예를 들면 fadeInp로 예를 들면 10초뒤에 서서히 나타나고, 나타나는데 5초가 걸린다는 뜻이다.

import React, { useEffect, useRef } from 'react';
import ReactDOM from 'react-dom';
import './index.css';

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

const App = () => {
  const fadeInH1 = useFadeIn(1, 2);
  const fadeInp = useFadeIn(5, 10);

  return(
    <div className="App">
      <h1 {...fadeInH1}>Hello</h1>
      <p {...fadeInp}>see you next</p>
    </div>
  )
};

ReactDOM.render(<App />, document.getElementById('root'));

 

2) useNetwork

navigator가 online 또는 offline인지 확인해준다.

 

확인은 console창에서 network에서 online상태 offline상태로 돌려주면서 확인한다.

console에서 확인하는것은 UI만 바뀌는 것 같으므로 console에 찍히도록 handleNetwork function을 만들어줘서 

log에 찍히는 것을 확인하도록 했다.

online상태 offline상태인것을 확인할때 유용할 것 같다.

import React, { useEffect, useState, useCallback } from 'react';
import ReactDOM from 'react-dom';
import './index.css';

const useNetwork = (onChange)=>{
  const [status, setStatus] = useState(navigator.onLine);
  const handleChange = useCallback(()=>{
      if(typeof onChange ==="function") {
        onChange(navigator.onLine);
      }
      setStatus(navigator.onLine)
    }, 
    [onChange])

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

const App = () => {
  const handleNetworkChange = (online)=>{
    console.log(online? "We just went online" : "We are offline");
  }
  const online = useNetwork(handleNetworkChange);
  return (
    <div>
      <h1>{online ? "onLine" : "offLine"}</h1>
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById('root'));

useScroll & useFullscreen

1) useScroll

스크롤에 반응하는 hooks이다.

 

스크롤은 y에만 해당한다.

scroll을 생성해주기위해서 div에 1000짜리 스크롤을 생성해주었다.

스크롤을 내릴때 hello 색상이 변경되는 것을 확인하기 위해서 hello 위치를 fixed로 고정했다.

y에 onScroll 함수를 적용해주었으므로 onScroll 함수에 window.scrollY와 X에 반응하도록 해주었다.

y값이 변할때 hello 색갈이 변하는 것을 확인할 수 있다.

import React, { useEffect, useState, useCallback } from 'react';
import ReactDOM from 'react-dom';
import './index.css';

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

const App = () => {
  const {y} = useScroll();
  return (
    <div className="App" style={{height: "1000vh"}}>
      <h1 style={{position: 'fixed', color: y > 100? "red" : "blue"}}>hello</h1>
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById('root'));

 

2) useFullscreen

전체화면과 전체화면을 벗어나게 할 수 있다.

현재 코드는 chrom에서만 적용되어서 다른 firefox나 safari, 인터넷익스플로어 등에서 적용되도록 하려면 tirgger, exitfull 함수에 if else로 웹페이지들에 적용되도록 작성해줘야한다.

 

-- 전체화면이 아닐때 전체화면 벗어나기 버튼을 누르면 페이지 오류가뜬다.

import React, { useRef } from 'react';
import ReactDOM from 'react-dom';
import './index.css';

const useFullscreen = (callback) => {
  const element = useRef();

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

  const triggerFull = () => {
    if (element.current) { element.current.requestFullscreen(); } 
    runCallback(true);
  }

  const exitFull = () => {
    if (document.exitFullscreen) { document.exitFullscreen(); }
    runCallback(false);
  }
  return { element, triggerFull, exitFull }
}

const App = () => {
  const onFullscreen = (isFull)=>{
    console.log(isFull ? "We are Full" : "We are small");
  }
  const {element, triggerFull, exitFull} = useFullscreen(onFullscreen);
  return (
    <div>
      <div ref={element}>
      <img  src="https://lh3.googleusercontent.com/proxy/CDTPaOv_NOGy8ZmbQ64SqmhNIx5jw8Q8Q5y0RqfZVZUGhuvWVZJkK4RR8WV4_PVclquvCLVbmdr5751NMSS2D4qZU5d5WkBjS0aL6ONNoEmOjZ1H6euGumnn4aCGRK6GYRmSzJr6NADc71sRUBVkZdMnCHsB84fnT5M" alt="푸들"/>
      <button onClick={exitFull}>전체화면빠져나오기</button>
      </div>
      <button onClick={triggerFull}>전체화면적용</button>
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById('root'));

useNotification

알람이 실행되는 function이다.

 

api 참고할수있는 페이지이다.(https://developer.mozilla.org/ko/docs/Web/API/notification)

 

 

import React, {  } from 'react';
import ReactDOM from 'react-dom';
import './index.css';

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

const App = () => {
  const triggerNotification = useNotification("알림이다", {body : "'알림씹지마바밥'"});
  return (
    <div>
      <button onClick={triggerNotification}>알림버튼</button>
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById('root'));

useAxios

 

axios는 http를 request 하는것이다.

 

useAxios.js 파일을 만들어준다.

import defaultAxios from 'axios';
import { useState, useEffect } from 'react';

const useAxios = (options, axiosInstance = defaultAxios)=>{ // axios 객체를 받지못하면 import한 axios사용
    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(()=>{
      if(!options.url) return;

      axiosInstance(options)
      .then(response=>{ setState({ ...state, loading : false, data : response.data}) })
      .catch(error=>{ setState({ ...state, loading : false, error }) }) }

      ,[axiosInstance, options, state, trigger])
      
    return {state, refetch};
}

export default useAxios;

App.js

 

반응형
LIST
Comments