React Hook(2)

한상현·2021년 1월 28일
0

Hook

목록 보기
2/4

📌UseInput

  • 기본적으로 input을 업데이트 하는 일.
  • 꽤 어려움 주의
useInput 사용법
const useInput = (initialValue, validator) => {
  // useInput 매개변수에는 초기값 : initialValue, 유효값 : validator 넣어준다.
  // validator를 넣는 것은 선택.(글자길이제한,글자유형제한)
  const [value, setValue] = useState(initialValue);
  //useState로 value의 초기값 설정. 
  const onChange = (event) => {
    const {
      target: { value }
    } = event;
    let willUpdate = true;
    //유효값 설정. false이면 update X
    if (typeof validator === "function") {
      willUpdate = validator(value);
    }
    //validator의 type이 function이면 validator(value) 삽입.
    if (willUpdate) {
      setValue(value);
    }
    //willUpdate가 true이면 setValue에 value 값 삽입.
  };
  return { value, onChange };
};
const App = () => {
  const maxLen = (value) => value.length <= 10;
  //maxLen true, false값 만들어 useInput으로 보냄.
  const name = useInput("Mr.", maxLen);
  //Mr가 기본값.
  return (
    <div className="App">
      <h1>hello</h1>
      <input placeholder="Name" {...name} />
	//{...name} : name을 진열. <-> value = {name.value}
    </div>
  );
};

😂 처음에는 비교적 어려울 수 있으나 보다보면 이해가능.
1. const [value,setValue] = useState(element);

  • useState를 사용. useState(element)에서 element값을 defautl값으로 설정.
  • element값은 밑의 App() 함수에서의 "Mr."
  1. const onChange = event ...
  • const {target:{value}} = event <- message:e.target.value 오른쪽의 코드가 왼쪽처럼 사용이 가능. 비구조화 할당 인건가???
  • willUpdate = validator(value) validator 함수는 App에서 넘겨받은 함수. value의 길이에 따라 true or false로 반환.
  • if(willUpdate){ setValue(value)} : willUpdate의 값이 true이면?? value값으로 갱신. false이면 갱신❌.
  1. App함수에서 {...name}은 name에 return된 두개의 값 : value, onChange 값을 가져온다는 의미.

📌UseTabs

  • content를 가져올 때 사용.
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;
  }
  //배열이 아닐 때 return
  const [currentIndex, setCurrentIndex] = useState(initialTab, allTabs);
  return {
    currentItem: allTabs[currentIndex],
    changeItem: setCurrentIndex
    //changeItem은 기본적으로 setCurrentIndex를 가짐.
  };
};
const App = () => {
  const { currentItem, changeItem } = useTabs(0, content);
  //content[0]을 얻고싶다. 배열의 인덱스가 0일때 첫번째 요소를 가져온다.
  //useTabs은 currentItem을 return
  return (
    <div className="App">
      {content.map((section, index) => (
        <button onClick={() => changeItem(index)}>{section.tab}</button>
        //index는 0 혹은 1
        //onClick이면 changeItem(index) 실행.
      ))}
      <div>{currentItem.content}</div>
    </div>
  );
};

😥 코드 설명

  1. API에서 데이터를 가져올 때를 가정.
  2. content.map을 통해 두개의 버튼을 생성.
    • index로 changeItem의 매개변수값 설정.
    • section.tab으로 버튼의 이름 설정.
  3. useTabs
    • initialTab: Tab의 초깃값 설정.
    • if(!allTabs || !Array.isArray(allTabs)) : allTabs가 true이거나 배열이 아닐 때 return;
    • currentItem, changeItem을 return;
  4. App
    • useTabs함수로 초기값 0으로 설정.
    • button을 click하였을 때 click한 button의 index값을 changeItem으로 넘겨줌.
    • changeItem에서 index에 맞는 값을 설정. -> 그에 맞는 content값 넘겨줌.

📌UseEffect

  • componentDidMount, componentWillUnmount, componentWillUpdate의 역할을 수행.
  • 두 개의 매개변수
    • 첫 번째 : 실행할 함수.
    • 두 번째 : dependency, ex) [number] 이면 number 변수가 변해야 함수가 실행, []이면 mount될 때만.
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";

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>
  );
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, document.getElementById("root"));

😂 코드 설명‼
1. useState(initialTitle)로 title의 default 값을 useState로 설정.(이 코드에서는 "Loading...")
2. innerText를 통해 title값을 설정.
3. useEffect(updateTitle, [title]) : updateTitle함수를 시작했을 때, 그리고 title이 변한 경우, 두번 실행.
- componentDidMount, componentWillUpdate 실행.
4. titleUpdater 변수는 useTitle의 return값 두개를 가지고 옴.
5. setTimeout함수로 5000ms 후에 titleUpdater("Home")의 값 가져옴.
6. titleUpdater 변수는 setTitle를 return 하고 있기에 매개변수값으로 "Home"을 넘겨주면 setTitle("Home")으로 받음.

📌UseRef, UseClick

  • UseRef : getElementById의 역할을 수행.
  • const input = useRef(), <input ref={input} />처럼 사용.
import React, { useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom";

const useClick = (onClick) => {
  const element = useRef();
  useEffect(() => {
    if (element.current) {
      element.current.addEventListener("click", onClick);
    } //dependency가 []인 경우 : componentDidMount, componentDidUpdate 때 호출.
    //dependency가 존재한다면 : componentDidMount일 때만 호출., componentDidUnMount일 때는 return
    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}>Hi</h1>
    </div>
  );
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, document.getElementById("root"));

😂 코드 설명
1. useEffect(() => {})

- if문을 통해 element.current의 유무 체크.
- onClick함수를 선언.
- 앞의 if문은 component가 mount될 때 실행.
- dependency에 []이기에 update될 때를 고려하지 않아도 됨, componentDidMount일 때 단 한번만 실행.
- dependency가 ""빈칸이면 update될 때마다 event가 추가됨. ❌
- unmount일 때 return 실행. event를 remove.
  1. const sayHello =() => ~

    • useclick(sayHello) : sayHello 함수가 실행.
  2. return () => {} : componentWillUnmount일 때의 ~

출처 : <노마드 코더>

profile
의 공부 노트.

0개의 댓글