0Pricing
React Native Academy · 강의

사용자 지정 훅 작성하기

상태를 사용하는 로직을 재사용 가능한 사용자 지정 훅으로 추출하고 두 컴포넌트에서 공유하며 훅의 이름 규칙과 사용 규칙을 따릅니다.

사용자 지정 훅 작성하기은(는) CoddyKit의 무료 React Native Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 React Native Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. React Native Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.

What Are Custom Hooks?

Custom hooks are JavaScript functions whose names start with use and that may call other React hooks inside them. They let you extract stateful logic from a component into a reusable function. The logic is shared, but each component that calls the custom hook gets its own isolated state — custom hooks are not singletons.

The Rules of Hooks Apply to Custom Hooks

Custom hooks follow the same rules as built-in hooks: only call hooks at the top level (not inside loops or conditions), and only call hooks from React function components or other custom hooks. The use naming prefix is required — it signals to React and linters that the function follows these rules.

// Valid custom hook — starts with 'use'
function useCounter(initialValue) {
  const [count, setCount] = useState(initialValue);
  const increment = () => setCount(c => c + 1);
  const decrement = () => setCount(c => c - 1);
  const reset = () => setCount(initialValue);
  return { count, increment, decrement, reset };
}

A useCounter Custom Hook

The useCounter hook encapsulates a counter's state and its increment, decrement, and reset actions. Any component that needs a counter can call useCounter without repeating the state management logic. Each call to the hook creates an independent counter.

function CounterScreen() {
  const { count, increment, decrement, reset } = useCounter(0);

  return (
    <View>
      <Text>Count: {count}</Text>
      <Button title='+' onPress={increment} />
      <Button title='-' onPress={decrement} />
      <Button title='Reset' onPress={reset} />
    </View>
  );
}

A useFetch Custom Hook

A useFetch hook wraps the common pattern of fetching data with useEffect: it manages loading, data, and error states internally, and exposes them to the component. The URL is a dependency — changing it re-triggers the fetch.

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    setLoading(true);
    fetch(url)
      .then((res) => res.json())
      .then((json) => { setData(json); setLoading(false); })
      .catch((err) => { setError(err); setLoading(false); });
  }, [url]);

  return { data, loading, error };
}

Using the useFetch Hook

Components using useFetch become dramatically simpler. The component only describes what to render for each state (loading, error, data) without managing any fetch logic itself. If the same endpoint is needed in another screen, just call useFetch again — no code duplication.

function PostsScreen() {
  const { data, loading, error } = useFetch('https://jsonplaceholder.typicode.com/posts');

  if (loading) return <ActivityIndicator />;
  if (error) return <Text>Error: {error.message}</Text>;

  return (
    <FlatList
      data={data}
      keyExtractor={(item) => String(item.id)}
      renderItem={({ item }) => <Text>{item.title}</Text>}
    />
  );
}

A useToggle Custom Hook

A useToggle hook simplifies managing boolean state that needs to switch between true and false. It is useful for modals, accordions, dark mode, or any feature that toggles. The hook returns the current value and a stable toggle function.

function useToggle(initialValue = false) {
  const [value, setValue] = useState(initialValue);
  const toggle = useCallback(() => setValue((v) => !v), []);
  return [value, toggle];
}

// Usage
const [isVisible, toggleVisible] = useToggle(false);
<Button title='Show/Hide' onPress={toggleVisible} />
<Modal visible={isVisible} ... />

A useForm Custom Hook

A useForm hook manages a form's field values, change handler, and reset action. This pattern eliminates boilerplate in forms across the app. The hook accepts an object of initial field values and returns the current values, a generic field change handler, and a reset function.

function useForm(initialValues) {
  const [values, setValues] = useState(initialValues);

  const handleChange = useCallback((field, value) => {
    setValues((prev) => ({ ...prev, [field]: value }));
  }, []);

  const reset = useCallback(() => setValues(initialValues), [initialValues]);

  return { values, handleChange, reset };
}

A useNetworkStatus Custom Hook

A useNetworkStatus hook wraps the NetInfo API to expose the device's online/offline status. Components can simply read the boolean value without knowing about event subscription setup and teardown — the hook handles that internally with a useEffect cleanup function.

import NetInfo from '@react-native-community/netinfo';

function useNetworkStatus() {
  const [isOnline, setIsOnline] = useState(true);

  useEffect(() => {
    const unsubscribe = NetInfo.addEventListener((state) => {
      setIsOnline(state.isConnected ?? true);
    });
    return unsubscribe; // cleanup on unmount
  }, []);

  return isOnline;
}

Sharing Logic Between Components

The real power of custom hooks is sharing logic, not UI. Two screens can both call useNetworkStatus and each gets its own subscription. If the hook has a side effect (like a subscription), it is automatically cleaned up when the component using it unmounts. Each component's hook instance is fully independent.

// Both screens share the same logic, not the same state
function HomeScreen() {
  const isOnline = useNetworkStatus();
  return <Text>{isOnline ? 'Online' : 'Offline'}</Text>;
}

function ProfileScreen() {
  const isOnline = useNetworkStatus(); // independent subscription
  return <Banner visible={!isOnline} message='No connection' />;
}

Custom Hook Naming and Organization

Name custom hooks descriptively: useAuth, useCart, useDebounce, useWindowDimensions. Store hooks in a dedicated hooks/ directory to keep them organized and findable. Each hook should have a single clear responsibility — avoid creating hooks that do five unrelated things.

// Project structure
src/
  hooks/
    useAuth.js
    useFetch.js
    useForm.js
    useToggle.js
    useNetworkStatus.js

A useDebounce Custom Hook

A useDebounce hook delays propagating a value until a specified time has passed since the last update. This is perfect for search inputs where you want to wait until the user stops typing before firing an API request. The hook uses useEffect and a timer to manage the delay.

function useDebounce(value, delay) {
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    const timer = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);
    return () => clearTimeout(timer);
  }, [value, delay]);

  return debouncedValue;
}

// Usage
const debouncedQuery = useDebounce(searchQuery, 400);
useEffect(() => { fetchResults(debouncedQuery); }, [debouncedQuery]);

Quick Check

Test your understanding of writing custom hooks from this lesson.

Lesson Recap

In this lesson you learned: custom hooks are functions starting with 'use' that encapsulate stateful logic, each component calling a custom hook gets its own independent state and effects, and organize hooks in a dedicated hooks/ directory for a single responsibility per hook. Next up we explore the Context API for sharing global state without prop drilling.

자주 묻는 질문

“사용자 지정 훅 작성하기” 강의는 무료인가요?

네 — “사용자 지정 훅 작성하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 React Native Academy 강의 전체를 잠금 해제할 수 있습니다. React Native Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“사용자 지정 훅 작성하기”에서 뭘 배우나요?

상태를 사용하는 로직을 재사용 가능한 사용자 지정 훅으로 추출하고 두 컴포넌트에서 공유하며 훅의 이름 규칙과 사용 규칙을 따릅니다. 브라우저에서 직접 실행하는 실습 코드로 React Native Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

React Native Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 React Native Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“사용자 지정 훅 작성하기” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 React Native Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 React Native Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. DOM 노드와 변경 가능한 값에 useRef 사용하기
  2. 복잡한 상태 로직에 useReducer 사용하기
  3. 성능을 위한 useCallback과 useMemo
  4. 사용자 지정 훅 작성하기
← React Native Academy(으)로 돌아가기