๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
WEB/Front-End๐ŸŒ

[React Hooks] useConfirm, preventLeave, useBeforeLeave

by narang111 2021. 12. 19.

useConfirm

- ์‚ฌ์šฉ์ž๊ฐ€ ๋ฌด์–ธ๊ฐ€๋ฅผ ํ•˜๊ธฐ์ „์— ํ™•์ธํ•˜๋Š” ๊ฑด๋ฐ 

์˜ˆ๋ฅผ ๋“ค๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋Š” ์ž‘์—…์„ ํ•˜๋ฉด ์ด๋ฒคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์ „์— ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

 

useConfirm๋งŒ ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ

- ํ™•์ธ์„ ๋ˆ„๋ฅด๋ฉด delete, ์ทจ์†Œ๋ฅผ ๋ˆ„๋ฅด๋ฉด abort๊ฐ€ ์ฝ˜์†”์— ์ถœ๋ ฅ๋œ๋‹ค.

import "./styles.css";
import React, { useState, useEffect, useRef } from "react";

const useConfirm = (message = "", callback, rejection) => {
  if (typeof callback !== "function") {
    return;
  }
  const confirmAction = () => {
    if (confirm(message)) {
      callback();
    } else{
      rejection();
    }
  };
  return confirmAction;
};

export default function App() {
  const deleteWorld = () => console.log("deleting");
  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>
  );
}

 

 

preventLeave

- ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ์ €์žฅ๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ™์ด ๋‚˜์˜ค๋Š” ๊ฑฐ

import "./styles.css";
import React, { useState, useEffect, useRef } from "react";

const usePreventLeave = () => {
  //API๊ฐ€ ์‘๋‹ตํ•œ ๊ฒƒ์— ๋”ฐ๋ผ ์ €์žฅ๋˜์—ˆ๋Š”์ง€, ์•„๋‹Œ์ง€ ๋“ฑ์„ ํ™•์ธ
  // ๋‹ซ์•„๋„ ๋ฉ๋‹ˆ๊นŒ?
  const listener = (event) => {
    event.preventDefault();
    event.returnValue = "";
  };
  const enablePrevent = () => window.addEventListener("beforeunload", listener);
  const disablePrevent = () =>
    window.removeEventListener("beforeunload", listener);
  return { enablePrevent, disablePrevent };
};

// protect๋ฅผ ๋ˆ„๋ฅด๊ณ  ์ฐฝ์„ ๋„๋ ค๊ณ ํ•˜๋ฉด ์•Œ๋ฆผ์ฐฝ์ด ๋œฌ๋‹ค.
export default function App() {
  const { enablePrevent, disablePrevent } = usePreventLeave();
  return (
    <div className="App">
      <button onClick={enablePrevent}>Protect</button>
      <button onClick={disablePrevent}>Unprotect</button>
    </div>
  );
}

 

 

 

useBeforeLeave

- ์ผ๋‹จ ์•„๋ž˜์ฝ”๋“œ๋Š” ์›นํŽ˜์ด์ง€๋ฅผ ๋ฒ—์–ด๋‚ฌ์„ ๋•Œ leaving์„ ์ฝ˜์†”์— ์ถœ๋ ฅํ•œ๋‹ค.

import "./styles.css";
import React, { useState, useEffect, useRef } from "react";

const useBeforeLeave=(onBefore) =>{
  if(typeof onBefore !== "function"){
    return;
  }
  const handle = ()=>{
    console.log("leaving");
  };
  useEffect(()=>{
    document.addEventListener("mouseleave", handle);
    return () =>{
      document.removeEventListener("mouseleave", handle);
    }
  }, []);
};

export default function App() {
  const begForLife = () => console.log("please dont leave");
  useBeforeLeave(begForLife);
  return(
    <div className="App">
      <h1>Hello</h1>
    </div>
  );
}

 

 

์ด๋ ‡๊ฒŒ clientY๋กœ ๋งˆ์šฐ์Šค๊ฐ€ ์œ„๋กœ ๊ฐˆ ๋•Œ๋งŒ ๋™์ž‘ํ•˜๊ฒŒ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

import "./styles.css";
import React, { useState, useEffect, useRef } from "react";

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("please dont leave");
  useBeforeLeave(begForLife);
  return(
    <div className="App">
      <h1>Hello</h1>
    </div>
  );
}