본문 바로가기
📗 React

ReactHooks 정복하기 1탄 ( useState, useClick )

by Tamii 2021. 4. 6.
반응형

기본적인 구조

useHooks라는 Hook이 있을 경우

const useHooks = (initial, ~) =>{

	const [ curr, setCurr ] = useState(initial, ~);
    
    return {
    	currItem : curr,
        changeItem: setCurr
    }
}


const App = () =>{

	const {currItem , changeItem} = useHooks(초기값);
    
    <div>
    	{currItem}
    	{changeItem(0)}
    </div>
}

 


🔥 useState 🔥

 

useInput

(초기값 , 유효검사function)

input 을 넣고, 원하는 입력 조건에 해당하는 값만 받기

//useInput Hooks
const useInput = (initialValue, validator) => {

	//useState : [값, 행할 함수] array 변환
  const [value, setValue] = useState(initialValue);
  
  //입력값에 변화 감지
  const onChange = (event) => {
  
    const {
      target: { value }
    } = event;
    
    //input에 넣어줄지 말지 결정
    let WillUpdate = true;
    
    //validator를 받았다면 =>validator함수 동작 (여기서는 maxLen)
    if (typeof validator === "function") {
      WillUpdate = validator(value);
    }
    
    //validator 동작 여부에 따라 state refresh
    if (WillUpdate) {
      setValue(value);
    }
  };
  return { value, onChange };
};

////////////////////////////////////////////////////////////////////

const App = () => {
	//validator 함수 
  const maxLen = (value) => value.length <= 10;
  
  //useInput 실행 및 초기값 지정
  const name = useInput("Mr.", maxLen);
  
  //렌더링
  return (
    <div className="App">
      <h1>Hello</h1>
      <input placeholder="Name" value={name.value} onChange={name.onChange} />
    </div>
  );
};

렌더링 시 name으로 받아오기 가능 

 

 

{...name}

name안에 있는것 풀어서 전달해줌

useInput에서 return 한 {value, onChange} name으로 받음

 

<input placeholder="Name" value={name.value} onClick ={name.onClick} />

<input placeholder="Name" {...name} />

 

 

 

validator 다양한 조건 입력 가능 

const App = () => {
  const validEmail = (value) => value.includes("@");
  const name = useInput("Mr.", validEmail);

 

다른  function에서 이벤드를 처리할 수 있음

 

 


useTabs

tab(다른 객체)와 index를 이용하여 재랜더링 하기

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

❗️ 동작 설명

❖ conten를 map으로 돌며 button 생성, onClick 이벤트 지정 

 

❖ button 클릭 -> 

changeItem(i)   :  setCurrengIndex(i)   : currentIndex를 i로 설정 

 

❖ allTabs(=content) 가 없거나 배열이 아니면 그냥 return 


🔥 useEffect 🔥 

uesEffect는 class component방식의 componentDidMount, componentDidUpdate 의 역할을 함

재랜더링할 때, state를 update할 때 실행하기 때문

useEffect ( 실행할 함수(?) , [변화를 감지할 배열]

배열 내의 존재가 변화하면 함수를 실행함 

import React, { useEffect, useState } from "react";

const App = () => {
  const sayHello = () => console.log("helo");
  const [num, setNum] = useState(0);
  const [anum, setaNum] = useState(0);
  useEffect(sayHello, [num]);

  return (
    <div className="App">
      <button onClick={() => setNum(num + 1)}>{num}</button>
      <button onClick={() => setaNum(anum + 1)}>{anum}</button>
    </div>
  );
};

export default App;

 

useEffect(sayHello , [num])

num이 변화하면 sayHello 함수가 실행된다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

useEffect( sayHello, [])

[] 빈배열일 경우엔

sayHello 는 처음 render 시 한번만 동작하고

그 후에  동작하지 않는다.

 

 

 

 

 

 

 

 

 

 

 

 

 

useEffect로 변화를 감지하고 componentWillUpdate하며 다양한 기능사용이 가능해진다!!!!

 


useTitle

변경한 title을 전달하면 웹페이지 title이 변경되는 동작

const useTitle = (initialTitle) => {

  const [title, setTitle] = useState(initialTitle);

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


const App = () => {

  const titleUpdater = useTitle("Loading...");
  
  setTimeout(() => titleUpdater("home"), 5000);
  
  return (
    <div className="App">
      <h1>hello</h1>
    </div>
  );
};

 

 

 

 

 

useRef

getElementById 와비슷한 기능으로 component의 일정 요소를 가져올 수 있음 

react 의 모든 component는 ref element(속성(을 가지고 있음 

const p = useRef();

console.log(p.current)  // <input ~요소 

<input ref={p} placeholder="la" />

p = 아래 input요소

 

uesClick

component요소를 가져와서 click 시 function 실행 

//component요소를 가져와서 click 시 function 실행 
const useClick = (onClick) => {
  if (typeof onClick !== "function") return;
  const element = useRef();
  useEffect(() => {
    if (element.current) {
      element.current.addEventListener("click", onClick);
    }
    return () => {
      if (element.current) {
        element.current.removeEventListener("click", onClick);
      }
    };
  }, []);
  return element;
};

/////////////////////////////////////

const App = () => {
  const sayhello = () => console.log("say hello");
  const title = useClick(sayhello);
  return (
    <div className="App">
      <h1 ref={title}>hello</h1>
    </div>
  );
};

useEffect (  함수 ( 함수1 ,함수2(return 함수) , dependecy 배열)

현재 useEffect의 함수는 return함수를 가지고 있다. 

 

react는 render 시 각각이 상황에 맞게 실행이 되는데  참고: (rrecoder.tistory.com/98?category=955706)

* componentDidMount()

* componentDidUpdate()

* componentWillUmnmonut()

 

 

❖dependency 배열 없을 시

useEffect( 함수 )

componentDidMount()  componentDidUpdate() 일때 실행

 

❖ dependencuy 배열 = []

useEffect( 함수, [] )

componentDidMount() 일때 실행

 

❖ return 함수가 있다면

useEffect( 함수(.. return함수) , [])

 

return 함수는 componentWillUmnmonut() 일때 실행

 

⭐️ 이벤트 리스너를 클릭시 한번 실행되게 만들고 싶다면 [] 와 return 함수를 지정해줘야 함

 component가 mount되지 않앗을 때 이벤트 리스너가 배치되지 않도록 없애야하기 때문

 

 

이어서 다른 Hook도 알아보도록 하자

 

 

 

 


참고한 강의는 노마드 코더의 실전형 리액트 Hooks 10개 입니다.

 

nomadcoders.co/react-hooks-introduction/lectures/1596

 

All Courses – 노마드 코더 Nomad Coders

초급부터 고급까지! 니꼬쌤과 함께 풀스택으로 성장하세요!

nomadcoders.co

 

댓글