React Hooks-02

chaaerim·2022년 2월 20일
0

React Hooks

목록 보기
2/2

오늘은 useTabs을 만들어 보면서 useState에 대한 공부를 마무리하고 useEffect로 넘어가보려 한다 !

useTabs

import { useState } from "react";
import React from "react";
import ReactDOM from "react-dom";

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 = () => {
  return (
    <div className="App">
      {content.map(section=>(
      <button>{section.tab}</button>
      ))}
    </div>
  );
};

export default App;
  • 내가 선택한 section의 content만 보여주고 싶음. -> 즉 Section2 버튼을 누르면 자동으로 content가 "I’m the content of the Section 2”로 바뀌게 하는 것.

useTabs

import { useState } from "react";
import React from "react";
import ReactDOM from "react-dom";

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)=>{
  if(!allTabs || !Array.isArray(allTabs)){
    return;
  } 
  const [currentIndex, setCurrentIndex]=useState(initialTab)
  return{
    currentItem: allTabs[currentIndex], 
    changeItem: setCurrentIndex
  };
};

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;
  • useTabs function이 시작할 때 에러 확인 allTabs가 true가 아니거나, allTabs가 배열이 아니라면 종료시킴.
  • content.map((section, index)에서 index는 0또는 1이 되어야하고 모든 버튼은 onClick 이벤트를 가짐.
  • button 에서 누군가 클릭하면 index가 무엇이든지 상관없이 changeItem(Index) 을 실행.-> 이는 setCurrentIndexitem을 바꿔줌. 따라서 currentItemcurrentIndex를 바꿔줌.

useEffect

useEffect는 componentWillUnmountcomponentDidMount, componentDidUpdate와 비슷.


const App = () => {
  const sayHello = () => console.log("hello");
  useEffect(() => {
    sayHello();
  });

  const [number, setNumber] = useState(0);
  const [aNumber, setAnumber] = useState(0);
  return (
    <div className="App">
      <div>hi</div>
      <button onClick={() => setNumber(number + 1)}>{number}</button>
      <button onClick={() => setAnumber(aNumber + 1)}>{aNumber}</button>
    </div>
  );
};


  • 첫번째 버튼을 클릭하면 숫자가 업데이트 되고 콘솔에도 hello가 뜸. 두번째 버튼도 마찬가지로 sayHello를 실행시킴.
  • useEffect는 componentDidMount의 역할을 해서 새로고침을 하면 sayHello를 실행하고 componentDidUpdate의 역할도 하기 때문에 버튼을 클릭하면 sayHello를 실행.
  • useEffect의 첫번째 인자는 function으로서의 effect가 됨. 두번째 인자는 deps로 만약 deps가 있다면 effect에는 deps리스트에 있는 값일 때만 값이 변하도록 활성화 됨.

dependency 살펴보기


const App = () => {
  const sayHello = () => console.log("hello");

  const [number, setNumber] = useState(0);
  const [aNumber, setAnumber] = useState(0);
  useEffect(sayHello, [number]);
  • useEffect가 sayHello를 component가 mount될 때 실행, 그리고 number가 바뀔 때만 sayHello를 실행. -> 이것이 dependency.
  • 만약 component가 Mount될 때만 실행시키고 싶다면 빈 dependency를 전달하면 됨.
    => 즉 dependency가 매우 중요하다 !!!

useTitle

문서의 제목을 업데이트 시켜주는 것을 담당하는 hook을 만들어보자!!

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">
      <div>hi</div>
    </div>
  );
};
  • titleUpdater는 setTitle과 동일함. 그러나 기본값을 "loading.."으로 설정.
  • 일단 useEffect가 mount되면 htmlTitle은 “loading…”이 됨.
  • 어딘가에서 titleUpdater를 부른다면 title이 바뀌게 됨. deps를 설정해줬으므로 title이 바뀔 때만 updateTitle이 불림.


  • 위 상단의 title이 변하는 것을 확인할 수 있음 !

마무리

다음에는 useEffect를 활용한 hooks를 몇가지 더 만들어보겠습니다 !!

0개의 댓글