본문 바로가기
WEB/Front-End🌝

[React Hooks] useInput, useTabs

by narang111 2021. 12. 13.

사람들은 자신의 hooks를 NPM에 공유할 수 있다.

https://www.npmjs.com/search?q=user&ranking=popularity 

 

user - npm search

 

www.npmjs.com

 

 

작업은 Code Sandbox에서 할 것이다.

https://codesandbox.io/

 

CodeSandbox: Online Code Editor and IDE for Rapid Web Development

Optimized for frameworks Custom environments built specifically for React, Vue, Angular, and many more.

codesandbox.io

 

Hooks는 react의 state machine에 연결하는 기본적인 방법이다.

 

코드를 더 이쁘게 만들어주고, 클래스를 사용하지않고, 모든것이 함수형 프로그래밍이 된다.

 

CodeSandbox로 간단하게 작성한 코드이다.

useState를 사용해서 숫자를 올리고내리는 코드이다.

hooks가 생기기 전에 state를 함수형 component에 사용할 수 없었다.

우리가 state를 가지고 작업을 하고싶으면 class component 형태로 만들어야했다.

class component는 this와 같은 문장 규칙과 render와 같은 것을 사용해야했지만 hooks를 사용한다면 고려할 필요없다.

 

 

useInput

useinput은 기본적으로 입력을 업데이트한다.

value가 10글자 이상이 되면 입력이 되지 않도록 함수도 넣어줬다.

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

// 2. validator가 바뀌면
const useInput = (initialValue, validator) => {
  const [value, setValue] = useState(initialValue);
  const onChange = (event) => {
    const {
      target: { value }
    } = event;
    let willUpdate = true;
    // 3. 타입이 function이라면
    if (typeof validator === "function") {
      // 4. willUpdate에 validator 결과를 업로드
      willUpdate = validator(value);
    }
    if (willUpdate) {
      setValue(value);
    }
  };
  return { value, onChange };
};

export default function App() {
  // 5. 이 케이스에서 validator는 maxLen이고
  // 결과는 true 또는 false 이다 (length<10?)
  const maxLen = (value) => value.length <= 10;
  // 1. useInput 함수에 Mr.와 maxLen을 넣고 name으로 받음
  const name = useInput("Mr.", maxLen);
  return (
    <div className="App">
      <h1>Hello</h1>
      <input placeholder="Name" {...name} />
    </div>
  );
}

10글자 이상이 되면 더 이상 입력되지 않는다.

 

'@'가 들어가는지, 들어가지 않는지 검사하는 것처럼 응용할 수 있다.

앞에 느낌표를 붙였기 때문에 @는 입력되지 않는다. (입력해도 업데이트 되지 않는다)

const maxLen = (value) => !value.includes("@");

 

 

 

useTabs >> 실패,,

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

const content = [
  {
    tab: "Section 1",
    content: "content of section1"
  },
  {
    tab: "Section 2",
    content: "content of section2"
  }
];

const useTabs = (initialTab, allTabs) => {
  const [currentIndex, setCurrentIndex] = useState(initialTab);
  if (!allTabs || Array.isArray(allTabs)) {
    return;
  }
  return {
    currentItem: allTabs[currentIndex],
    changeItem: setCurrentIndex
  };
};

export default function 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>
  );
}