Sobes.tech
Junior

Reactте кандай hookтар бар?

sobes.tech AI

AIден жооп

React-те, 16.8 версиясынан бери, хуктар функциялык компоненттерге абал башкарууга жана жашоо циклин колдонууга мүмкүнчүлүк берет, ал мурда гана класстагы компоненттерге жеткиликтүү болгон:

Мына негизги встроенген хуктар:

  • useState: функциялык компонентке ички абалды кошууга мүмкүндүк берет. Ал учурдагы абалды жана аны жаңыртуу үчүн функцияны кайтарат:

    // useState мисал
    import React, { useState } from 'react';
    
    function Counter() {
      const [count, setCount] = useState(0); // баштапкы мааниси 0
    
      return (
        <div>
          <p>Сиз басканыз {count} жолу</p>
          <button onClick={() => setCount(count + 1)}>
            Мени бас
          </button>
        </div>
      );
    }
    
  • useEffect: функциялык компоненттерде жанама таасирлерди аткарууга мүмкүндүк берет. Ал класстагы жашоо циклинин методдоруна (componentDidMount, componentDidUpdate, componentWillUnmount) окшош.

    // useEffect мисал
    import React, { useState, useEffect } from 'react';
    
    function Example() {
      const [count, setCount] = useState(0);
    
      // ар бир рендерден кийин иштейт
      useEffect(() => {
        document.title = `Сиз басканыз ${count} жолу`;
      });
    
      // биринчи рендерде гана иштейт (бош массивтин көз карандычылыгы)
      useEffect(() => {
        console.log('Компонент орнотулду');
        return () => {
          console.log('Компонент алынып салынды'); // тазалоо функциясы
        };
      }, []);
    
      // count өзгөргөндө иштейт
      useEffect(() => {
        console.log('Count өзгөрдү:', count);
      }, [count]);
    
      return (
        <div>
          <p>Сиз басканыз {count} жолу</p>
          <button onClick={() => setCount(count + 1)}>
            Мени бас
          </button>
        </div>
      );
    }
    
  • useContext: React контекстинин өзгөрүшүнө жазылууга мүмкүндүк берет. Ал React.createContext() менен түзүлгөн контекст объектисин кабыл алат:

    // useContext мисал
    import React, { useContext } from 'react';
    
    const ThemeContext = React.createContext('light'); // контекст түзүү
    
    function ThemedButton() {
      const theme = useContext(ThemeContext); // контекстти колдонуу
    
      return (
        <button className={theme}>
          Тема {theme} боюнча баскыч
        </button>
      );
    }
    
    function App() {
      return (
        <ThemedButton />
      );
    }
    
  • useReducer: useStateке альтернатива, көбүрөөк структураланган абалды башкаруу үчүн, мисалы бир нече маанилерди камтыган же кийинки абал алдынкыга көз каранды болгондо:

    // useReducer мисал
    import React, { useReducer } from 'react';
    
    const initialState = { count: 0 };
    
    function reducer(state, action) {
      switch (action.type) {
        case 'increment':
          return { count: state.count + 1 };
        case 'decrement':
          return { count: state.count - 1 };
        default:
          throw new Error();
      }
    }
    
    function Counter() {
      const [state, dispatch] = useReducer(reducer, initialState);
    
      return (
        <>
          <p>Сана: {state.count}</p>
          <button onClick={() => dispatch({ type: 'increment' })}>+</button>
          <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
        </>
      );
    }
    
  • useCallback: кайтару функциясын мемоизациялайт. ал кайтарылган функцияны кайсы бир көз карандычылык өзгөргөндө гана өзгөртөт. бул балдар компоненттеринин кайра рендерлерин алдын алуу үчүн пайдалуу:

    // useCallback мисал
    import React, { useState, useCallback } from 'react';
    
    function Parent({ addTodo }) {
      const [count, setCount] = useState(0);
    
      const handleAddTodo = useCallback(() => {
        addTodo();
      }, [addTodo]); // көз карандычылык addTodo
    
      return (
        <>
          <button onClick={() => setCount(count + 1)}>
            эсептегичти көбөйт
          </button>
          <Child onAddItem={handleAddTodo} />
        </>
      );
    }
    
    function Child({ onAddItem }) {
      console.log('Child кайра рендерделүүдө'); // only when onAddItem өзгөрөт
      return <button onClick={onAddItem}>Элемент кошуу</button>;
    }
    
  • useMemo: маанини мемоизациялайт. ал көз карандычылык өзгөргөндө гана кайра эсептелет. бул кымбатчылык эсептөөлөр үчүн пайдалуу:

    // useMemo мисал
    import React, { useMemo, useState } from 'react';
    
    function expensiveCalculation(num) {
      console.log('Кымбатчылык эсептөө жүргүзүлүүдө...');
      for (let i = 0; i < 1000000; i++) {
        num += 1;
      }
      return num;
    }
    
    function Example() {
      const [count, setCount] = useState(0);
      const [todos, setTodos] = useState([]);
    
      const calculation = useMemo(() => expensiveCalculation(count), [count]); // көз карандычылык count
    
      const addTodo = () => {
        setTodos(t => [...t, "Жаңы Todo"]);
      };
    
      return (
        <div>
          <div>
            <h2>Менин Todo-лерим</h2>
            {todos.map((todo, index) => (
              <p key={index}>{todo}</p>
            ))}
            <button onClick={addTodo}>Todo кошуу</button>
          </div>
          <hr />
          <div>
            эсеп: {count}
            <button onClick={() => setCount(c => c + 1)}>+</button>
            <h2>Кымбатчылык эсептөө</h2>
            {calculation}
          </div>
        </div>
      );
    }
    
  • useRef: мутабельдүү реф түзүүгө мүмкүндүк берет, ал бүтүндөй компоненттин жашоо циклинде сакталат. көбүнесе DOM элементтерине жетүү же мутабельдүү маанини сактоо үчүн колдонулат, ал өзгөргөндө кайра рендер жасабайт:

    // useRef мисал
    import React, { useRef } from 'react';
    
    function TextInputWithFocusButton() {
      const inputEl = useRef(null); // реф түзүү
    
      const onButtonClick = () => {
        // current монтолгон DOM элементин көрсөтөт
        inputEl.current.focus();
      };
    
      return (
        <>
          <input ref={inputEl} type="text" /> // реф байлоо
          <button onClick={onButtonClick}>Киргизүү талагына фокус коюу</button>
        </>
      );
    }
    
  • useImperativeHandle: экземплярдык дескрипторду конфигурациялайт, ал ата-эне компоненти ref аркылуу алууга мүмкүндүк берет. ал баланын компонентине белгилүү ыкмаларды ачыкка чыгууга мүмкүндүк берет. forwardRef менен колдонулат:

    // useImperativeHandle мисал
    import React, { useRef, useImperativeHandle, forwardRef } from 'react';
    
    const MyInput = forwardRef((props, ref) => {
      const inputRef = useRef();
    
      useImperativeHandle(ref, () => ({
        focusInput: () => {
          inputRef.current.focus();
        }
      }));
    
      return <input ref={inputRef} {...props} />;
    });
    
    function ParentComponent() {
      const inputRef = useRef();
    
      const handleFocus = () => {
        inputRef.current.focusInput(); // баладан метод чакыруу
      };
    
      return (
        <div>
          <MyInput ref={inputRef} />
          <button onClick={handleFocus}>Фокус берүү</button>
        </div>
      );
    }
    
  • useLayoutEffect: useEffect сыяктуу, бирок синхрондуу иштейт жана DOM өзгөртүүлөрдөн кийин, браузер экранды жаңыртпей туруп иштейт:

    // useLayoutEffect мисал
    import React, { useLayoutEffect, useRef } from 'react';
    
    function Tooltip({ children, text }) {
      const ref = useRef(null);
    
      useLayoutEffect(() => {
        if (ref.current) {
          const { top, height } = ref.current.getBoundingClientRect();
          console.log(`Элемент ${top} бийиктикте, бийиктиги ${height}`);
        }
      }, [children]);
    
      return (
        <span ref={ref} title={text}>
          {children}
        </span>
      );
    }
    
  • useDebugValue: колдонучу хуктардын React DevTools-деги белгилерин көрсөтөт:

    // useDebugValue мисал
    import React, { useState, useDebugValue } from 'react';
    
    function useFriendStatus(friendID) {
      const [isOnline, setIsOnline] = useState(null);
    
      useDebugValue(isOnline === true ? 'Онлайн' : 'Офлайн');
    
      // ... досунун абалын алуу логикасы
    
      return isOnline;
    }
    
    function FriendListItem({ friend }) {
      const isOnline = useFriendStatus(friend.id);
    
      return (
        <li style={{ color: isOnline ? 'жашыл' : 'кара' }}>
          {friend.name} - {isOnline ? 'Онлайн' : 'Офлайн'}
        </li>
      );
    }
    

Кошумча, колдонуучу хуктары (Custom Hooks) да бар. Бул JavaScript функциялары, алардын аты "use" менен башталат жана кайра колдонулушу мүмкүн:

// Колдонуучу хуктун мисалы
import { useState, useEffect } from 'react';

function useWindowSize() {
  const [size, setSize] = useState([window.innerWidth, window.innerHeight]);

  useEffect(() => {
    const handleResize = () => {
      setSize([window.innerWidth, window.innerHeight]);
    };
    window.addEventListener('resize', handleResize);
    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []);

  return size;
}

function MyComponent() {
  const [width, height] = useWindowSize(); // колдонуучу хукту колдонуу

  return (
    <p>Терезе өлчөмү: {width}x{height}</p>
  );
}

Маанилүү: хуктарды колдонуу эрежелерин сактоо:

  1. Хукты React компонентинин жогорку деңгээлинде же колдонуучу хуктунда гана чакырыңыз. Циклдерде, шарттарда же ички функцияларда чакырбоңуз.
  2. Хукты React функциялык компоненттерден же колдонуучу хуктардан гана чакырыңыз. Жалпы JavaScript функцияларынан же класстык компоненттердин методдорунан чакырбоңуз.