React Hooks — ano ito, mga pangunahing hooks at panuntunan sa paggamit

May-akda: IT Sectr Nai-publish: 2026-07-04 Oras ng pagbabasa: 10 min

React Hooks — ay mga function na nagpapahintulot sa paggamit ng state, effects, context at iba pang kakayahan ng React sa functional components, nang hindi nagsusulat ng mga klase. Ipinakilala sa React 16.8, ang mga hooks ay radikal na nagbago ng approach sa pag-develop, pinalitan ang mga kumplikadong pattern tulad ng HOC at render props. Ayon sa React, 2024, mayroong 15 built-in na hooks na sumasaklaw sa lahat ng senaryo ng pamamahala ng component.

Pangunahin

  • Hooks — mga function para sa pagkonekta ng mga kakayahan ng React sa functional components nang walang extends Component.
  • useState — pangunahing hook para sa pamamahala ng state, nagbabalik ng halaga at setter.
  • useEffect — para sa side effects: mga API request, subscription, timer, DOM manipulations.
  • useContext — para sa access sa React context nang walang Consumer wrappers at static contextType.
  • Mga panuntunan ng hooks — tawagan lamang sa pinakamataas na antas at lamang sa loob ng functional components o custom hooks.

Ano ang React Hooks?

React Hooks — isang set ng mga built-in na function sa React na nagpapahintulot ng ‘pagkokonekta’ sa panloob na mekanismo ng framework nang hindi gumagawa ng mga klase. Bago ang React 16.8, ang mga functional component ay maaari lamang tumanggap ng props at magbalik ng JSX — anumang komplikadong lohika ay nangangailangan ng class component.

Ang problema ng mga class component — paghihiwalay ng kaugnay na lohika. Ang code na nauukol sa isang entity (halimbawa, WebSocket subscription) ay napipilitang hatiin sa pagitan ng componentDidMount, componentDidUpdate at componentWillUnmount. Ang mga hooks ay lumulutas nito: lahat ng lohika ay pinagsama-sama sa iisang useEffect.

Ang pangalawang problema — muling paggamit ng lohika. Para sa muling paggamit ng state logic sa pagitan ng class components, kailangang mag-apply ng HOC (higher-order components) o render props — parehong pattern ay lumilikha ng karagdagang nesting sa component tree. Ang mga custom hooks ay lumulutas sa problemang ito nang walang nesting.

useState — pamamahala ng state

useState — ang pinakapangunahing hook. Tumatanggap ito ng paunang halaga at nagbabalik ng tuple: ang kasalukuyang halaga at isang function para sa pag-update nito. Hindi tulad ng this.setState sa mga klase, ang useState ay hindi pinagsasama ang mga bagay — ang bagong state ay ganap na pinapalitan ang nauna para sa isang partikular na tawag sa useState.

js
import React, { useState } from 'react';

function Form() {
  const [text, setText] = useState('');
  const [submitting, setSubmitting] = useState(false);

  async function handleSubmit() {
    setSubmitting(true);
    await fetch('/api/submit', {
      method: 'POST',
      body: JSON.stringify({ text })
    });
    setSubmitting(false);
  }

  return (
    <div>
      <input
        value={text}
        onChange={e => setText(e.target.value)}
      />
      <button onClick={handleSubmit}
        disabled={submitting}>
        {submitting ? 'Saving...' : 'Submit'}
      </button>
    </div>
  );
}

Functional na anyo ng setState

Ang setter ng useState ay maaaring tumanggap ng isang function na tumatanggap ng nakaraang halaga at nagbabalik ng bago. Functional na anyo ay sapilitan kapag ang bagong state ay kinakalkula mula sa nauna at posible ang mga batch na tawag sa setState — bawat tawag ay makakakuha ng napapanahong nakaraang halaga.

useEffect — side effects at lifecycle

useEffect — hook para sa pagsasagawa ng side effects sa functional components. Tumatanggap ito ng dalawang argumento: isang effect function at isang dependency array. Isinasagawa ng React ang effect pagkatapos ng bawat render, ngunit kapag tinukoy ang mga dependency — lamang kapag ang alinman sa mga ito ay nagbago.

Ang isang walang laman na dependency array [] ay nangangahulugan na ang effect ay isinasagawa nang isang beses pagkatapos ng unang render (kahalintulad ng componentDidMount). Ang pagbabalik ng function mula sa effect ay cleanup, na isinasagawa sa pag-unmount (kahalintulad ng componentWillUnmount) at bago ang muling pagsasagawa ng effect.

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

function ChatRoom({ roomId }) {
  const [messages, setMessages] = useState([]);

  useEffect(() => {
    const socket = new WebSocket(`wss://chat/${roomId}`);

    socket.onmessage = (event) => {
      setMessages(prev => [...prev, JSON.parse(event.data)]);
    };

    // Cleanup - isara ang socket
    return () => socket.close();
  }, [roomId]);

  return <ul>
    {messages.map((msg, i) =>
      <li key={i}>{msg.text}</li>
    )}
  </ul>;
}

Ang mga dependency ng useEffect — ay ang tanging koneksyon sa pagitan ng effect at ng panlabas na mundo. Kung sa effect ay ginagamit ang isang variable mula sa props o state, ito ay dapat nasa dependency array. Ang pagbalewala sa panuntunang ito ay pinagmumulan ng mga bug na may luma na data (stale closure).

useContext — access sa context

useContext — hook para sa pagbabasa ng halaga ng context. Tumatanggap ito ng context object na ginawa ng React.createContext at nagbabalik ng kasalukuyang halaga. Kung nagbago ang context, ang component ay awtomatikong magre-render gamit ang bagong halaga.

Bago ang pagdating ng useContext, ang access sa context sa functional components ay nangangailangan ng pambalot sa Context.Consumer, na lumilikha ng nesting. useContext ay ganap na nag-aalis ng Consumer — sapat na ang tawagan ang hook sa kahit saang bahagi ng functional component.

js
import React, { createContext, useContext } from 'react';

const ThemeContext = createContext('maliwanag');

function ThemedButton() {
  const theme = useContext(ThemeContext);

  return <button
    className={`btn btn-${theme}`}
  >
    {theme === 'dark' ? 'moon' : '☀️'}
  </button>;
}

Ang useContext ay hindi kapalit ng Redux o global state. Inirerekomenda ng React ang paggamit ng context para sa mga bihirang nagbabagong halaga — tema, wika, awtorisasyon. Para sa madalas na ina-update na data, ang bawat re-render ay muling kukuwentahin ang lahat ng consumer ng context, na maaaring magpababa ng performance.

useReducer — komplikadong lohika ng state

useReducer — alternatibo sa useState para sa mga state na may komplikadong update logic. Tumatanggap ito ng reducer function at paunang state, nagbabalik ng kasalukuyang state at dispatch function. Ang reducer ay tumatanggap ng kasalukuyang state at action, nagbabalik ng bagong state — isang purong function na walang side effects.

Ang useReducer ay lalong kapaki-pakinabang kapag maraming aksyon (set, reset, increment, addItem) ang namamahala sa iisang state. Sa halip na maraming useState na may iba’t ibang setter — isang reducer na may malinaw na action types. Ito ay ginagawang predictable at madaling i-test ang lohika.

js
import React, { useReducer } from 'react';

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { ...state, count: state.count + 1 };
    case 'setStep':
      return { ...state, step: action.step };
    case 'reset':
      return { count: 0, step: 1 };
    default:
      throw new Error('Unknown action: ' + action.type);
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, {
    count: 0,
    step: 1
  });

  return (
    <>
      <p>Count: {state.count}</p>
      <button
        onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button
        onClick={() => dispatch({ type: 'reset' })}>Reset</button>
    </>
  );
}

useRef, useMemo, useCallback — optimisasyon

useRef ay lumilikha ng isang nababagong bagay na nananatili sa pagitan ng mga render. Ang pagbabago ng current ay hindi nagdudulot ng re-render. Pangunahing gamit — access sa DOM elements at pag-iimbak ng mga nababagong halaga (timer, nakaraang halaga, instance ng mga library).

useMemo ay nagme-memoize ng resulta ng isang function. Kinukuwenta nito muli ang halaga lamang kapag nagbago ang isa sa mga dependency. Gamitin para sa mahal na kalkulasyon — pag-filter ng malalaking array, pag-sort, pag-format ng data. useCallback — isang espesyal na kaso ng useMemo para sa pagme-memoize ng mga function.

js
import React, { useRef, useMemo, useCallback } from 'react';

function SearchPage({ items, query, onItemSelect }) {
  const inputRef = useRef(null);

  // Autofocus sa mount
  useEffect(() => {
    inputRef.current?.focus();
  }, []);

  // i-memoize ang na-filter na resulta
  const filtered = useMemo(() => {
    return items.filter(item =>
      item.name.toLowerCase()
        .includes(query.toLowerCase())
    );
  }, [items, query]);

  // i-memoize ang callback
  const handleSelect = useCallback((id) => {
    onItemSelect(id);
  }, [onItemSelect]);

  return (
    <div>
      <input ref={inputRef}
        value={query}
        onChange={e => setQuery(e.target.value)}
      />
      <ul>
        {filtered.map(item =>
          <li key={item.id}>
            <button
              onClick={() => handleSelect(item.id)}>
              {item.name}
            </button>
          </li>
        )}
      </ul>
    </div>
  );
}

Mahalagang panuntunan: useRef, useMemo at useCallback — mga kasangkapan sa optimisasyon, hindi sapilitang konstruksyon. Huwag balutin ang lahat sa useMemo — sukatin muna ang performance. Ang napaagang optimisasyon ay nagpapakumplikado ng code. Ang React ay nagre-render ng mga component nang mabilis; ang useMemo ay kailangan lamang kapag ang mga kalkulasyon ay talagang mahal (O(n²) at mas mataas).

Mga panuntunan ng hooks at karaniwang pagkakamali

Ipinakilala ng React ang dalawang mahigpit na panuntunan para sa hooks. Una: tawagan ang hooks lamang sa pinakamataas na antas — hindi sa loob ng mga kondisyon, loop, o nested function. Pangalawa: tawagan ang hooks lamang mula sa React functional components o custom hooks. Ang ESLint plugin na eslint-plugin-react-hooks ay awtomatikong nagsusuri ng parehong panuntunan.

Ang pinakakaraniwang pagkakamali — paglabag sa pagkakasunod-sunod ng pagtawag ng hooks. Ang React ay umaasa sa pagkakasunod-sunod ng pagtawag ng hooks sa pagitan ng mga render. Kung ang isang hook ay nasa loob ng kondisyon at hindi natawag sa isa sa mga render, lahat ng kasunod na hook ay lumilipat, na nagdudulot ng mga bug.

PagkakamaliAno ang nangyayariSolusyon
Hook sa kondisyonNasisira ang pagkakasunod-sunod ng hooksIlipat ang lohika ng kondisyon sa loob ng hook
Stale closureGumagamit ang effect ng lumang halagaIdagdag lahat ng dependency sa array
Walang katapusang loopBinabago ng useEffect nang walang dependency ang stateTukuyin ang mga dependency o gumamit ng useReducer
Pagbabago ng ref sa renderSide effect sa katawan ng functionIlipat ang mga mutasyon sa useEffect

Ang pangalawang karaniwang pagkakamali — stale closure sa useEffect. Kung sa effect ay ginagamit ang isang variable na hindi tinukoy sa mga dependency, ang effect ay ‘nakakakuha’ ng halaga nito sa sandali ng paggawa ng closure. Solusyon — laging isama ang lahat ng ginamit na variable sa dependency array. Kung napakaraming dependency, hatiin ang effect sa ilang bahagi.

Mga Madalas Itanong

Bakit hindi maaaring tawagan ang mga hooks sa mga kondisyon?

Ang React ay umaasa sa pagkakasunod-sunod ng pagtawag ng hooks sa pagitan ng mga render. Kung ang isang hook ay tinawag sa kondisyon at hindi gumana sa isa sa mga render, lahat ng kasunod na hook ay ‘lumilipat’ — ang kanilang state ay naghahalo. Ang ESLint rule na hooks/exhaustive-deps ay nagbabala tungkol dito.

Ano ang pagkakaiba ng useEffect at useLayoutEffect?

useLayoutEffect ay synchronous at isinasagawa bago iguhit ng browser ang mga pagbabago. useEffect ay asynchronous — pagkatapos ng pagguhit. Gamitin ang useLayoutEffect lamang kapag kailangang sukatin o baguhin ang DOM bago makita ng user ang mga pagbabago (posisyon ng popover, pag-restore ng scroll).

Paano kanselahin ang fetch request sa pag-unmount?

Gumamit ng AbortController sa loob ng useEffect. Gumawa ng controller, ipasa ang signal sa fetch, at sa cleanup function ay tawagan ang controller.abort(). Para sa lumang browser, sapat na ang cancelled flag: return () => { cancelled = true; } na may pagsusuri bago ang setState.

Ano ang custom hook at kailan ito gagawin?

Custom hook — isang JavaScript function na may prefix na use na gumagamit ng built-in na hooks. Gawin ito kapag ang parehong lohika na may hooks ay paulit-ulit sa dalawa o higit pang component. Halimbawa: useDebounce, useLocalStorage, useMediaQuery. Ang custom hooks ay pumapalit sa HOC at render props.

Bakit dalawang beses isinasagawa ang useEffect sa Strict Mode?

Sa Strict Mode, sinasadya ng React na i-mount at i-unmount ang component nang dalawang beses sa development mode upang makahanap ng mga error sa hindi nalinis na effects. Kung ang cleanup ay isinulat nang tama, ang dobleng tawag ay hindi nagdudulot ng problema. Sa production mode hindi ito nangyayari.

Buod

  • React Hooks — mga function para sa paggamit ng state, effects at context sa functional components, na pumalit sa mga klase.
  • useState — pangunahing hook para sa lokal na state na may functional setter para sa ligtas na pag-update.
  • useEffect — unibersal na hook para sa side effects na may dependency array at cleanup function.
  • useContext — direktang access sa React context nang walang Consumer wrappers at karagdagang nesting.
  • useReducer — para sa komplikadong state logic na may action types, alternatibo sa Redux sa loob ng isang component.
  • useRef, useMemo, useCallback — mga kasangkapan sa optimisasyon: DOM references, memoization ng values at callbacks.
  • Panuntunan ng pinakamataas na antas — mahigpit na limitasyon sa pagtawag ng hooks sa labas ng kondisyon, loop at nested function.

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din