728x90
    
    
  SMALL
    - 이번 글에서는 useCallback에 대해서 이야기해보겠습니다.
useCallback
1) 역할
- useCallback은 React Component에서 메모이제이션된 Callback function을 생성하기 위한 Hook입니다.
- 주로 불필요한 rendering을 방지하고 성능을 최적화하는 데 사용됩니다.
- useCallback을 통해 함수의 참조 동일성을 유지해서 자식 component의 불필요한 re-rendering을 막을 수 있습니다.
2) 동작 방식
- useCallback은 메모이제이션된 callback function을 반환하는데,
- 첫 번째 인자로는 메모이제이션할 callback function을 받습니다.
- 두 번째 인자로 의존성 배열(dependency array)을 받습니다. 이 배열 내의 값들이 변경될 때만 새로운 함수가 생성됩니다.
 
- 의존성 배열이 변경되지 않으면 이전에 메모이제이션된 function을 반환합니다.
- 빈 배열([ ])을 전달하면 component의 생명주기 동안 항상 동일한 함수 참조를 유지합니다.
- 의존성 배열을 생략하면 매 rendering마다 새로운 함수를 생성하므로 useCallback의 이점이 사라집니다.
3) 간단한 예시 몇 가지!
- Re-rendering 최적화
import React, { useState, useCallback, useRef } from "react";
interface ChildProps {
  count: number;
  onIncrement: () => void;
  onDecrement: () => void;
  type: string;
}
const ChildComponent: React.FC<ChildProps> = React.memo(
  ({ count, onIncrement, onDecrement, type }) => {
    const renderCount = useRef(0);
    renderCount.current += 1;
    return (
      <Card>
        <CardTitle>{type} useCallback</CardTitle>
        <CountDisplay>{count}</CountDisplay>
        <ButtonGroup>
          <Button onClick={onDecrement}>-</Button>
          <Button onClick={onIncrement}>+</Button>
        </ButtonGroup>
        <RenderCount>Re-rendering: {renderCount.current}</RenderCount>
      </Card>
    );
  }
);
const UseCall: React.FC = () => {
  const [count1, setCount1] = useState(0);
  const [count2, setCount2] = useState(0);
  const [parentRender, setParentRender] = useState(0);
  const increment1 = useCallback(() => setCount1((c) => c + 1), []);
  const decrement1 = useCallback(() => setCount1((c) => c - 1), []);
  const increment2 = () => setCount2((c) => c + 1);
  const decrement2 = () => setCount2((c) => c - 1);
  return (
    <Container>
      <Title>useCallback Rendering</Title>
      <CardContainer>
        <ChildComponent
          count={count1}
          onIncrement={increment1}
          onDecrement={decrement1}
          type="With"
        />
        <ChildComponent
          count={count2}
          onIncrement={increment2}
          onDecrement={decrement2}
          type="Without"
        />
      </CardContainer>
      <ParentAction onClick={() => setParentRender((p) => p + 1)}>
        Parent Component Re-rendering
      </ParentAction>
      <RenderCount>Parent Re-rendering: {parentRender}</RenderCount>
      <Explanation>
        위 버튼으로 Parent Component를 Re-rendering 할 수 있어요!
        <br />
        useCallback을 사용한 Component는 불필요한 Re-rendering을 방지합니다.
      </Explanation>
    </Container>
  );
};
- API 호출 최적화
import React, { useState, useCallback, useEffect } from "react";
const UserSearch: React.FC = () => {
  const [userId, setUserId] = useState("");
  const [user, setUser] = useState<any>(null);
  const [apiCallCount, setApiCallCount] = useState(0);
  const fetchUser = useCallback(async () => {
    if (userId) {
      setApiCallCount((count) => count + 1);
      try {
        await new Promise((resolve) => setTimeout(resolve, 500));
        setUser({
          id: userId,
          name: `User ${userId}`,
          email: "user@example.com",
          phone: "010-1234-5678",
        });
      } catch (error) {
        console.error("Error fetching user:", error);
        setUser(null);
      }
    }
  }, [userId]);
  useEffect(() => {
    fetchUser();
  }, [fetchUser]);
  return (
    <Container>
      <Title>User Search</Title>
      <Input
        type="text"
        value={userId}
        onChange={(e) => setUserId(e.target.value)}
        placeholder="Enter user ID"
      />
      <Button onClick={fetchUser}>Fetch User</Button>
      {user && (
        <Result>
          <h2>{user.name}</h2>
          <p>Email: {user.email}</p>
          <p>Phone: {user.phone}</p>
        </Result>
      )}
      <ApiCallCount>API 호출 횟수: {apiCallCount}</ApiCallCount>
    </Container>
  );
};- useCallback Hook은 주로 자식 component에 함수를 props로 전달할 때나 useEffect의 의존성으로 함수를 사용할 때 유용합니다.
- 성능 최적화에 도움이 되지만, 모든 함수에 사용하는 것은 오히려 성능을 저하시킬 수 있으므로 적절히 사용해야 합니다.
- 다음 글에서는 useMemo에 대해서 알아보겠습니다.
728x90
    
    
  LIST
    'Projects > Conti:ed' 카테고리의 다른 글
| [Conti:ed] 개요 및 index.tsx (7) | 2024.12.18 | 
|---|---|
| [React] useRef (1) | 2024.07.03 | 
| [React] useEffect (1) | 2024.06.29 | 
| [React] useState (0) | 2024.06.28 | 
