React Hooks 10

SOO·2022년 10월 18일
0

basic

목록 보기
7/16

UseState

항상 2개의 value를 return함
첫번째 value를 item이라고 이름을 주고, 두번째 value는 값을 변경하게 함

  const [counter, setCounter] = React.useState(0);
      const onClick = () => {
        setCounter(counter + 1);
      };

데이터를 숫자형 데이터로 건네줄거고, 그 데이터 값을 바꿀 함수도 함께 줄거임. 그리고 그 함수를 이용해서 데이터를 바꿨을 때, 데이터 값이 바뀌고 컴포넌트도 동시에 리렌더링될 거임! 업데이트가 완료되는 것!

Q. 왜 useState는 let이 아니라 const를 사용할까 ?

정확하게 새로운 값을 부여하는게 아니기 때문! useState는 단순히 상태를 업데이트하는 함수이다!

UseInput

spread operator(스프레드 연산자)

https://www.techiediaries.com/react-spread-operator-props-setstate/
■ value={name.value} onChange.{name.onChange} 은
{...name} 과 같은 의미
안에 있는 모든 것을 un

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

useTabs

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

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) => {
  const [currentIndex, setcurrentIndex] = useState(initialTab);
  if (!allTabs || !Array.isArray(allTabs)) {
    return;
  }
  return { currentItem: allTabs[currentIndex], changeItem: setcurrentIndex// state를 업데이트 시키는거니까 };
};

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

export default App;

setstate는 rerendering 해주는거

useEffect

가끔은 특정 코드의 실행을 제한하고 싶다.
component가 맨 처음 render될 때만 말야!
그리고는 다시 실행 ㄴㄴ

useEffect는 두 개의 argument를 가지는 function
첫번째 argument는 우리가 딱 한번만 실행하고 싶은 코드가 될거임 - function으로써의 effect
두번째 argument는 정말 마법같은 친구 - deps(필수 ㄴ), deps list에 있는 값일 때만 값이 변하도록 활성화 될거임
useEffect function은 쉽게 말해서 우리 코드가 딱 한번만 실행될 수 있도록 보호해줘

  useEffect(() => {
    console.log("CALL THE API....");
  }, []);

어떤 일이 일어나도 이 코드는 딱 한 번만!

deps

  useEffect(() => {
    console.log("I run when 'keyword' changes.");
  }, [keyword]);

keyword가 변화할 때 코드를 실행하고 싶다면, 이 자리에 'keyword'라고 써줘.
여기서 하는 건 이 keyword가 변화할 때 코드를 실행할거라고 react.js에게 알려주는거야.
그래서 이 코드는 keyword가 변화할 때만 실행될거임

 useEffect(() => {
    console.log("I run only once.");
  }, []);

이게 바로 우리가 여기에 빈 array를 써 주었을 때 코드가 단 한번만 실행되는 이유임

ex) useEffect(sayHello, [number]);

useEffect가 sayHello를 component가 mount 되었을 때 실행시켰고, 그리고 number가 바뀔때만 실행됨

useEffect 왜 써?
렌더링이 계속 된다면, 특히 특정 api를 불러오게 되는 경우 계속해서 불러오는 문제가 생길 수 있음!
state를 변경할 때, 계속해서 렌더링 되는 문제점이 존재함.
많은 state가 존재한다면 성능 저하 문제가 발생할 있기에 이런 문제를 해결하기 위해 사용함!

useTitle

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

const App = () => {
	const titleUpdater = useTitle("Loading...");
    return (
    <div className="App">
    	<div>Hi</div>
    </div>    
    )
};

useClick

const useClick = (onClick) => {
const ref = useRef();
useEffect(() => {
const element = ref;
if (element.current) {
element.current.addEventListener("click", onClick);
}
return () => {
if (element.current) {
element.current.removeEventListener("click", onClick);
}
};
}, []);
if (typeof onclick !== "object") {
return;
}
return ref;
};

export default function App() {
const sayHello = () => console.log("sayHello");
const title = useClick(sayHello);
return (

);
}
  1. componentWillMount
    : element 의 click 이벤트 없애줌

  2. componentDidMount
    click 이벤트 등록 'sayHello'

  3. [] 의사용
    dependency 에 아무것도 들어가있지 않음 => 페이지가 redering 될 때 한 번만 동작

useConfirm & usePreventLeave

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

const App = () => {
	const deleteWorld = () => console.log("Deleting the world");
    const abort = () => console.log("Aborted"); //취소 
    const confirmDelete = useConfirm("Are you sure", deleteWorld);
	return (
    	<div clasName="App">
  <button onclick={confirmDelete}>Delete the world</button>
  </div>
    
    );
};
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 App = () => {
	const {enablePrevent, disablePrevent} = usePreventLeave();
    return <div className="App"><button onClick ={enablePrevent} >Protect</button><button onClick ={disablePrevent}>Unprotect</button></div>;
};

useBeoreLeave

const useBeorLeave = 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)
   },[]);
};


const App = () => {
	const beForLife = () => console.log("Pls dont leave");
    useBeforeLeave(beFor)
    return (
    	<div> className="App">
  <h1>Hello</h1>	
  		</div>
    );
};

useNotification

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

const App = () => {
	const triggerNotif = useNotification("Can I steal your food?")
	return (
  		<div className="App" style = {{ height:"1000vh"}}>
  			<button onClick={triggerNotif}>Hello</button>
  		</div>
  )

}

0개의 댓글