게으른개발너D

[Custom Hooks 1] useState 이용 본문

개발/ReactJS

[Custom Hooks 1] useState 이용

lazyhysong 2023. 10. 30. 17:52

1. custom hooks

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

hooks들을 code sandbox에서 구현 한 후 작동하는 걸 확인하면, 내 폴더 안에 넣고 그 다음 NPM directory에 등록시킬 것이다.

 

  1. useTitle: react document의 title을 몇 개의 hooks와 함께 바꾸는 것
  2. useInput: input 역할
  3. usePageLeave: 유저가 page를 벗어나는 시점을 발견하고 함수를 실행
  4. useClick: 누군가 element를 클릭하는 시점을 감지
  5. useFadeIn: 어떤 element든 상관없이 애니메이션을 element 안으로 서서히 사라지게 만듦
  6. useFullscreen: 어떤 element든 풀스크린으로 만들거나 일반 화면으로 돌아가게 함
  7. useHover: 어떤 것에 마우스를 올렸을 때 감지
  8. useNetwork: online or offline 상태 감지
  9. useNotification: notification API를 사용할 때 유저에게 알림을 보내줌
  10. useScroll: 스크롤을 사용할 때를 감지해 알려줌
  11. useTabs: 웹사이트 메뉴 또는 무엇이든 간에 tab을 사용하기 쉽게 만들어 주는 것
  12. usePreventLeave: 유저가 변경사항이나 무엇이든간에 저장하지 않고 페이지를 벗어나길 원할 때 확인을 하는 것
  13. useConfirm: 위와 유사하면서 어떠한 기능이 존재
  14. useAxios: HTTP requests client axios 을 위한 wrapper 같은 것

 

 

 

2. useState etc..

useState는 초기에 state를 InitialState 세팅 할 수 있는 옵션을 제공한다.

// const [item, setItem] = useState(initialSetting);

const [item, setItem] = useState(0);
const item = useState(0)[0];

react에서 제공하는 hooks들은 기본적으로, useState, useEffect, useContext 등이 있다.

추가적으로 useReducer, useCallback, useMemo, useRef, useImperativeHandle, useLayoutEffect, useDebugValue 가 있다.

 

 

 

 

3. useInput (custom)

input을 업데이트하는 hook을 만들어 볼 것이다.

https://www.youtube.com/watch?v=sZDvByH2mNU

노마트코더 유튜브에서 만든 것이 있는데 이것보다 더 좋게 만들어 볼 것이다.

 

3.1 custom hook

const useInput = (initialValue) => {
  const [value, setValue] = useState(initialValue);
  const onChange = (event) => {
    const { target: { value }} = event;
    setValue(value);
  }
  return { value, onChange };
};

 

useInput은 위과 같이 만들 수 있다.

 

3.2 use

function App() {
  const name = useInput("Miss.");
  return (
    <div className="App">
      <h1>Hello</h1>
      <input placeholder="Name" value={name.value} onChange={name.onChange} />
    </div>
  );
}

useInput에 initialValue 값인 "Miss."를 넣은 후 name이란 변수에 담았다.

이걸 input의 value와 onChange에 각각 사용하려면 name.value, name.onChange를 넣어주면 된다.

 

3.3 use spread operator

좀 더 짧고 간단하게 적어볼 수 있다. 

useInput에서 value와 onChange의 변수명을 그대로 둔 이유이기도 하다.

function App() {
  const name = useInput("Miss.");
  return (
    <div className="App">
      <h1>Hello</h1>
      <input placeholder="Name" {...name} />
    </div>
  );
}

{...name} 이렇게 스프레드 연산자를 쓰면 name에 있는 element 값들이 풀어져서 value는 name.value가 되고, onChange는 name.onChange가 될 것이다.

 

3.4 more functions

몇몇 input 마다 사람들이 특정 문자를 쓸 수 없게 하고 싶다.

유효성 검사하는 기능을 넣어보자.

useInput hook에 validator라는 매개변수를 넣고 onChange에 value를 세팅해주자.

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

validator의 type이 function인지 먼저 검사해준 후 함수라면 value 값을 validator에 넣어서 반환되는 boolean 값이 willUpdate의 값이 되게 만들었다.

willUpdate가 true여야 value의 값을 수정할 수 있다.

여기서 매개변수인 validator는 유효성 검사를 하는 함수이다.

 

이제 해당 hook을 사용해보자. 

먼저 validator로 넘겨줄 요효성 검사 함수를 작성해야한다.

function App() {
  const maxLen = (value) => value.length <= 10;
  const name = useInput("Miss.", maxLen);
  return (
    <div className="App">
      <h1>Hello</h1>
      <input placeholder="Name" {...name} />
    </div>
  );
}

validator 인자로 넘겨줄 maxLen이란 함수를 작성하고 useInput 두번째 인자로 넣어주었다.

input 안의 value 값이 10자 이상이 되면 더이상 input 안에 글자가 써지지 않을 것이다.

 

 

 

 

4. useTabs (custom)

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."
  }
];

export default function App() {
  return (
    <div className="App">
      {content.map((section) => (
        <button key={section.tab}>{section.tab}</button>
      ))}
    </div>
  );
}

이렇게 content란 변수를 만들고 section의 tab에 해당하는 버튼들을 만들었다.

 

나는 현재 내가 선택한 section의 content만 보여주고 싶다.

예를들어 처음에 section1의 content가 로드될 것이다. 그리고 section2를 클릭하면 section2의 content로 바뀔 것이다.

 

4.1 useTabs

useTabs hook을 만들어보자.

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

initial 값으로 설정할 initialTab 매개변수와 전체 컨텐츠에 해당하는 allTabs를 파라미터 값으로 넣었다.

여기서 allTabs는 배열이어야하므로 배열이 아닐 경우 return 하도록 구현했다.

 

4.2 use

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."
  }
];

function App() {
  const { currentItem, changeItem } = useTabs(0, content);
  return (
    <div className="App">
      {content.map((section, index) => (
        <button onClick={() => changeItem(index)} key={index}>
          {section.tab}
        </button>
      ))}
      <div>{currentItem.content}</div>
    </div>
  );
}

useTabs의 인자로 initial 값인 0과 content를 넣어주었다.

이제 tab element에 해당하는 버튼을 클릭시, 아래에 해당 tab의 content가 보여지게 된다.

 

 

 

 


출처

노마드코더

https://nomadcoders.co/react-hooks-introduction/

 

All Courses – 노마드 코더 Nomad Coders

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

nomadcoders.co

 

Comments