Hooks

Seungsoo Lee·2022년 7월 23일
0

Front-End

목록 보기
8/11

Hook 함수들

  • useState()

    • 만약 이렇게 코드를 짠다면,
import React, { useState } from "react";

function Counter(props) {
  var count = 0;
  
  return (
  	<div>
      <p>{count}번 클릭했습니다.</p>
      <button onClick={() => count++}>
        click!!
      </button>
    </div>
  );
}

count가 업데이트 되지 않을것이다.
따라서 useState를 사용해서 재렌더링 될때 업데이트를 시켜준다.

  • useState() 사용법
const [변수명, set함수명] = useState(초깃값);
  • useState()를 사용한 코드
import React, { useState } from "react";

function Counter(props) {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <p>{count}번 클릭했습니다.</p>
      <button onClick={() => setCount(count + 1)}>
        click!!
      </button>
    </div>
  );
}

이렇게 해서 useState()를 통해 재렌더링 될때 바뀌는 변수를 설정해주고 set함수를 통해 업데이트를 해준다.

  • useEffect()

    • useEffect() 사용법
useEffect(이펙트 함수, 의존성 배열);

의존성배열에서 값이 하나라도 변경되었을때 이펙트 함수가 실행됨.

useEffect(이펙트 함수, []);

이펙트 함수가 mount unmount시에 단 한번씩만 실행됨.

useEffect(이펙트 함수);

의존성 배열 생략시, 컴포넌트가 업데이트될 때마다 호출 됨.

  • 예시 코드
import React, { useState, useEffect } from "react";

function Counter(props) {
  const [count, setCount] = useState(0);
  
  useEffect(() => {
    document.title = 'You clicked ${count} times'; 
  });
  
  return (
    <div>
      <p>{count}번 클릭했습니다.</p>
      <button onClick={() => setCount(count + 1)}>
        click!!
      </button>
    </div>
  );
}

이 코드는 useEffect에 의존성 배열이 없기때문에 컴포넌트가 업데이트 될 때마다 호출이 된다. 즉 setCount로 count변수가 업데이트 될 때마다, 이펙트 함수가 실행이 될것이다.

  • useEffect() 정리
useEffect(() => {
  // 컴포넌트가 마운트 된 이후,
  // 의존성 배열에 있는 변수들 중 하나라도 값이 변경되었을 때 실행됨
  // 의존성 배열에 빈 배열([])을 넣으면 마운트와 언마운트시에 단 한 번씩만 실행됨
  // 의존성 배열 생략 시 컴포넌트 업데이트 시마다 실행됨
  ...
  
  return () => {
    // 컴포넌트가 마운트 
  }
}, [의존성 변수1, 의존성 변수2, ...]);
  • useMemo()

    • 렌더링이 일어날때마다 변수가 바뀌는게 싫을때 메모리변수에 잠시 저장후 사용할 수 있음
    • useMemo() 사용법
const memoizedValue = useMemo(
  () => {
    // 연산량이 높은 작업을 수행하여 결과를 반환
    return computeExpensiveValue(의존성 변수1, 의존성 변수2);
  },
  [의존성 변수1, 의존성 변수2]
);
  • 의존성 배열을 넣지 않을 경우, 매 렌더링마다 함수가 실행됨
const memmoizedValue = useMemo(
  () => computeExpensiveValue(a, b)
);
  • 의존성 배열이 빈 배열일 경우, 컴포넌트 마운트 시에만 호출됨
const memoizedValue = useMemo(
  () => {
    return computeExpensiveValue(a, b);
  },
  []
);
  • useCallback()

    • useMemo() 와 비슷하지만 값이 아닌 함수를 반환
    • useCallback() 사용법
const memoizedCallback = useCallback(
  () => {
    doSomething(의존성 변수1, 의존성 변수2);
  },
  [의존성 변수1, 의존성 변수2]
);

- 동일한 역할을 하는 코드들

useCallback(함수, 의존성 배열);

useMemo(() => 함수, 의존성 배열);
  • useRef()

    • Reference(특정 컴포넌트에 접근할 수 있는 객체)를 사용하기 위한 Hook
    • useRef() 사용법
const refContainer = useRef(초깃값);

Hook 규칙

  • Hook은 무조건 최상위 레벨에서만 호출해야 한다.

    • 반복문, 조건문, 중첩된 함수들 사이에서 Hook을 호출하면 안됨
    • Hook은 컴포넌트가 렌더링될 때마다 매번 같은 순서로 호출되어야 한다.
    • 잘못된 예시
function MyComponent(props) {
  const [name, setName] = useState('alvin');
  
  if (name !== '') {
    useEffect(() => {
      ...
    });
  }
              
  ...
}

렌더링 할때마다 hook이 같은 순서대로 호출되는것이 아니라 조건문의 결과에 따라 호출되는 hook이 달라지므로 잘못된 코드임.

  • 리액트 함수 컴포넌트에서만 Hook을 호출해야 한다.

Custom Hook

  • Custom Hook의 이름은 꼭 use로 시작해야한다.
  • 여러개의 컴포넌트에서 하나의 Custom Hook을 사용할때, 컴포넌트 내부에 있는 모든 state와 effects는 전부 분리되어있다.
    • 리엑트 컴포넌트는 각각의 Custom Hook 호출에 대해서 분리된 state를 얻기 때문이다.
  • 각 Custom Hook으ㅟ 호출 또한 완전히 독립적이다.
  • Custom Hook을 사용해야하는 예시 상황

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

function UserListItem(props) {
  const [isOnline, setIsOnline] = useState(null);
  
  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status, isOnline);
    }
    
    ServerAPI.subscribeUserStatus(props.user.id, handleStatusChange);
    return () => {
      ServerAPI.unsubscribeUserStatus(props.user.id, handleStatusChange);
    };
  });
  
  return (
    <li style={{ color: isOnline ? 'green' : 'black' }}>
      {props.user.name}
    </li>
  );
}

--> 중복된 로직 추출

import { useState, useEffect } from "react";

function useUserStatus(userId) {
  const [isOnline, setIsOnline] = useState(null);
  
  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status, isOnline);
    }
    
    ServerAPI.subscirbeUserStatus(userId, handleStatusChange);
    return () => {
      ServerAPI.unsubscribeUserStatus(userId, handleStatusChange);
    };
  });
  
  return isOnline;
}

=> Custom Hook 사용

function UserStatus(props) {
  const isOnline = useUserStatus(props.user.id);
  
  if (isOnline === null) {
    return '대기중...';
  }
  return isOnline ? '온라인' : '오프라인';
}

function UserListItem(props) {
  const isOnline = useUserStatus(props.user.id);
  
  return (
    <li style={{ color: isOnline ? 'green' : 'black' }}>
      {prop.user.name}
    </li>
  );
}

1개의 댓글

comment-user-thumbnail
2023년 4월 22일

People love to contribute some quality energy alone, getting a charge of a strange and incensed arranged life. People regularly go on a quick trip as it borders the capital of India, you can go on a quick excursion there as well.
https://www.sanakhan.in/bhiwadi-call-girls.html
https://www.sanakhan.in/bikaner-call-girls.html
https://www.sanakhan.in/bundi-call-girls.html
https://www.sanakhan.in/chandpole-call-girls.html
https://www.sanakhan.in/chittorgarh-call-girls.html

답글 달기