가수면

커스텀 훅 본문

React/React

커스텀 훅

니비앙 2022. 12. 10. 15:20

예제 코드)

input의 useState를 커스텀훅으로 만들어 대체해보기

// src/App.jsx

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

const App = () => {
        // input의 갯수가 늘어날때마다 state와 handler가 같이 증가한다.
  const [title, setTitle] = useState("");
  const onChangeTitleHandler = (e) => {
    setTitle(e.target.value);
  };

        // input의 갯수가 늘어날때마다 state와 handler가 같이 증가한다.
  const [body, setBody] = useState("");
  const onChangeBodyHandler = (e) => {
    setBody(e.target.value);
  };

  return (
    <div>
      <input
        type="text"
        name="title"
        value={title}
        onChange={onChangeTitleHandler}
      />
      <input
        type="text"
        name="title"
        value={body}
        onChange={onChangeBodyHandler}
      />
    </div>
  );
};

export default App;

 


1. hooks 폴더에 useInput.jsx라는 훅을 만듦

import React, { useState } from 'react'

const useInput = () => {
  const [value, setValue] = useState('')
  const handler = event => setValue(event.target.value)
  return [value, handler]
}

export default useInput

 

2.App.js에 커스텀 훅 적용하기

// src/App.jsx

  // const [title, setTitle] = useState("");
  // const onChangeTitleHandler = (e) => {
  //   setTitle(e.target.value);
  // };
  const [title, onChangeTitleHandler] = useInput()

  // const [body, setBody] = useState("");
  // const onChangeBodyHandler = (e) => {
  //   setBody(e.target.value);
  // };
  const [body, onChangeBodyHandler] = useInput()

 


스타일 훅 만들기

안되는 코드임. 방식만 참고

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

const useFadeIn = (duration = 1, delay = 0) => {
  if (typeof duration !== "number" || typeof delay !== "number") {
    return;
  }
  const element = useRef();
  useEffect(() => {
    if (element.current) {
      const { current } = element;
      current.style.transition = `opacity ${duration}s ease-in-out ${delay}s`;
      current.style.opacity = 1;
    }
  }, []);
  return { ref: element, style: { opacity: 0 } };
};

const test = () => {
  const fadeInH1 = useFadeIn(1, 2);
  const fadeInP = useFadeIn(5, 10);
  return (
    <div>
      <h1 {...fadeInH1}>안녕</h1>
      <p {...fadeInP}>반가워</p>
    </div>
  );
};

export default test;

 

기본 형태

import React, { useState } from 'react'

const useInput = (initialValue, validator) => {
  const [value, setValue] = useState(initialValue)
  const onChange = event => {
    // const { target: { value } } = event
    const { value } = event.target
    let willUpdate = true
    if (typeof (validator) === "function") {
      willUpdate = validator(value)
    }
    if (willUpdate) {
      setValue(value)
    }
  }
  return { value, onChange }
}

const App = () => {
  const maxLen = (value) => value.length <= 10
  const name = useInput("Mr.", maxLen)
  return (
    <div>
      <h1>안녕</h1>
      <input placeholder="Name" {...name} />
      {/* <input placeholder="Name" value={name.value} onChange={name.onChange} /> */}
    </div>
  )
}

export default App

 

스크롤 이벤트 훅

import React, { useEffect, useState } from 'react'

const useScroll = () => {
  const [state, setState] = useState({
    x: 0,
    y: 0
  })
  const onScroll = () => {
    setState({ x: window.screenX, y: window.scrollY })
  }
  useEffect(() => {
    window.addEventListener("scroll", onScroll)
    return () => window.removeEventListener("scroll", onScroll)
  }, [])
  return state
}

const App = () => {
  const { y } = useScroll()
  return (
    <div style={{ height: "1000vh" }}>
      <h1 style={{ position: "fixed", color: y > 100 ? "red" : "blue" }}>안녕</h1>
    </div>
  )
}

export default App

'React > React' 카테고리의 다른 글

로그인 (리액트 쿠키)  (0) 2022.12.22
useRef  (0) 2022.12.21
useMemo / useCallback  (0) 2022.12.10
리액트에서 모달창 띄우기  (0) 2022.12.07
map으로 돌릴 때 데이터 타입  (0) 2022.12.05
Comments