Sobes.tech
Junior

React'da qanday hooklar mavjud?

sobes.tech AI

AIdan javob

Reactda, versiya 16.8 dan boshlab, hooklar funksional komponentlarga holatni boshqarish va hayot aylanish tsikllaridan foydalanish imkonini beradi, ular ilgari faqat sinf komponentlar uchun mavjud edi.

Asosiy o'rnatilgan hooklar:

  • useState: Funktsional komponentga ichki holat qo'shishga imkon beradi. Juftlikni qaytaradi: hozirgi holat va uni yangilash uchun funksiya.

    // useState misoli
    import React, { useState } from 'react';
    
    function Counter() {
      const [count, setCount] = useState(0); // Holatni 0 ga boshlash
    
      return (
        <div>
          <p>Siz {count} marta bosdingiz</p>
          <button onClick={() => setCount(count + 1)}>
            Menga bos
          </button>
        </div>
      );
    }
    
  • useEffect: Funktsional komponentlarda yon ta'sirlarni bajarishga imkon beradi. Sinf komponentlarining hayot aylanishi metodlariga o'xshash (componentDidMount, componentDidUpdate, componentWillUnmount).

    // useEffect misoli
    import React, { useState, useEffect } from 'react';
    
    function Example() {
      const [count, setCount] = useState(0);
    
      // Har bir renderdan keyin ishga tushadi
      useEffect(() => {
        document.title = `Siz ${count} marta bosdingiz`;
      });
    
      // Faqat birinchi renderda ishga tushadi (bo'sh bog'liqlik ro'yxati)
      useEffect(() => {
        console.log('Komponent montaj qilindi');
        return () => {
          console.log('Komponent o'chirildi'); // Tozalash funksiyasi
        };
      }, []);
    
      // count o'zgarganda ishga tushadi
      useEffect(() => {
        console.log('Count o`zgardi:', count);
      }, [count]);
    
      return (
        <div>
          <p>Siz {count} marta bosdingiz</p>
          <button onClick={() => setCount(count + 1)}>
            Menga bos
          </button>
        </div>
      );
    }
    
  • useContext: React kontekst o'zgarishlariga obuna bo'lish imkonini beradi. React.createContext() yordamida yaratilgan kontekst ob'ektini qabul qiladi.

    // useContext misoli
    import React, { useContext } from 'react';
    
    const ThemeContext = React.createContext('light'); // Kontekst yaratish
    
    function ThemedButton() {
      const theme = useContext(ThemeContext); // Kontekstdan foydalanish
    
      return (
        <button className={theme}>
          Mavzudagi tugma {theme}
        </button>
      );
    }
    
    function App() {
      return (
        <ThemedButton />
      );
    }
    
  • useReducer: useState ga alternativ, murakkab holatlarni boshqarish uchun, bu holat bir nechta kichik holatlardan iborat bo'lsa yoki keyingi holat avvalgisiga bog'liq bo'lsa, ishlatiladi. Reduxdagi reducerlarga o'xshash.

    // useReducer misoli
    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 (
        <>
          Count: {state.count}
          <button onClick={() => dispatch({ type: 'increment' })}>+</button>
          <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
        </>
      );
    }
    
  • useCallback: Callback funksiyasini memoizatsiya qiladi. Faqat biror bir bog'liqlik o'zgarganda o'zgaradigan memoizatsiyalangan versiyasini qaytaradi. Bu, callbacklarni uzatishda, bolalar komponentlarning keraksiz qayta renderlanishini oldini olish uchun foydalidir.

    // useCallback misoli
    import React, { useState, useCallback } from 'react';
    
    function Parent({ addTodo }) {
      const [count, setCount] = useState(0);
    
      const handleAddTodo = useCallback(() => {
        addTodo();
      }, [addTodo]); // addTodo ga bog'liq
    
      return (
        <>
          <button onClick={() => setCount(count + 1)}>
            Hisobni oshirish
          </button>
          <Child onAddItem={handleAddTodo} />
        </>
      );
    }
    
    function Child({ onAddItem }) {
      console.log('Child qayta ishlanmoqda'); // faqat onAddItem o'zgarganda qayta ishlanadi
      return <button onClick={onAddItem}>Element qo'shish</button>;
    }
    
  • useMemo: Hisoblangan qiymatni memoizatsiya qiladi. Faqat bog'liqliklardan biri o'zgarganda qayta hisoblanadi. Bu, qimmatli hisoblashlar uchun, ishlash samaradorligini oshirish uchun foydalidir.

    // useMemo misoli
    import React, { useMemo, useState } from 'react';
    
    function expensiveCalculation(num) {
      console.log('Qimmatli hisoblash amalga oshirilmoqda...');
      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 ga bog'liq
    
      const addTodo = () => {
        setTodos(t => [...t, "Yangi vazifa"]);
      };
    
      return (
        <div>
          <div>
            <h2>Mening Todo'larim</h2>
            {todos.map((todo, index) => (
              <p key={index}>{todo}</p>
            ))}
            <button onClick={addTodo}>Todo qo'shish</button>
          </div>
          <hr />
          <div>
            Hisob: {count}
            <button onClick={() => setCount(c => c + 1)}>+</button>
            <h2>Qimmatli hisoblash</h2>
            {calculation}
          </div>
        </div>
      );
    }
    
  • useRef: O'zgarmas ref yaratishga imkon beradi, u butun komponent hayoti davomida saqlanadi. DOM elementlariga kirish yoki har qanday o'zgarmas qiymatni saqlash uchun ishlatiladi, bu o'zgartirish renderni chaqirmaydi.

    // useRef misoli
    import React, { useRef } from 'react';
    
    function TextInputWithFocusButton() {
      const inputEl = useRef(null); // ref yaratish
    
      const onButtonClick = () => {
        // current, DOM elementiga ishora qiladi
        inputEl.current.focus();
      };
    
      return (
        <>
          <input ref={inputEl} type="text" /> // ref bilan bog'lash
          <button onClick={onButtonClick}>Fokusni joylashtirish</button>
        </>
      );
    }
    
  • useImperativeHandle: Obyektni sozlaydi, u ref yordamida ota komponentga taqdim etiladi. Bolaga, ma'lum metodlarni ochishga imkon beradi. forwardRef bilan birga ishlatiladi.

    // useImperativeHandle misoli
    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(); // boladan metod chaqirish
      };
    
      return (
        <div>
          <MyInput ref={inputRef} />
          <button onClick={handleFocus}>Ona orqali fokus</button>
        </div>
      );
    }
    
  • useLayoutEffect: useEffect bilan bir xil, lekin barcha DOM o'zgartirishlardan keyin sinxron ravishda ishlaydi. DOM dan ma'lumot o'qish yoki brauzer ekranini yangilashdan oldin bajarilishi kerak bo'lgan o'zgartirishlar uchun foydalidir. Renderni to'xtatishi mumkin.

    // useLayoutEffect misoli
    import React, { useLayoutEffect, useRef } from 'react';
    
    function Tooltip({ children, text }) {
      const ref = useRef(null);
    
      useLayoutEffect(() => {
        if (ref.current) {
          // DOM asosida hisoblashlar
          const { top, height } = ref.current.getBoundingClientRect();
          console.log(`Element joylashuvi: ${top}, balandligi: ${height}`);
        }
      }, [children]);
    
      return (
        <span ref={ref} title={text}>
          {children}
        </span>
      );
    }
    
  • useDebugValue: React DevTools'da hooklar uchun foydalanuvchi belgisini ko'rsatadi. Maxsus hooklar uchun debuggingda ishlatiladi.

    // useDebugValue misoli
    import React, { useState, useDebugValue } from 'react';
    
    function useFriendStatus(friendID) {
      const [isOnline, setIsOnline] = useState(null);
    
      // DevTools'da 'Online' yoki 'Offline' ko'rsatadi
      useDebugValue(isOnline === true ? 'Online' : 'Offline');
    
      // ... do'st holatini olish logikasi
    
      return isOnline;
    }
    
    function FriendListItem({ friend }) {
      const isOnline = useFriendStatus(friend.id);
    
      return (
        <li style={{ color: isOnline ? 'green' : 'black' }}>
          {friend.name} - {isOnline ? 'Online' : 'Offline'}
        </li>
      );
    }
    

Bundan tashqari, foydalanuvchi hooklari (Custom Hooks) mavjud. Bu JavaScript funksiyalari bo'lib, nomlari "use" bilan boshlanadi. Ular komponentlar o'rtasida holat logikasini takror ishlatishga imkon beradi. Foydalanuvchi hook boshqa hooklarni chaqirishi mumkin.

// Foydalanuvchi hook misoli
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(); // Foydalanuvchi hook ishlatilmoqda

  return (
    <p>Oyna o'lchami: {width}x{height}</p>
  );
}

Hooklar qo'llash qoidalari:

  1. Hooklarni faqat React komponentining yuqori qismida yoki foydalanuvchi hookida chaqiring. Ularni tsikllar, shartlar yoki ichki funksiyalar ichida chaqirmang.
  2. Hooklarni faqat React funksional komponentlaridan yoki foydalanuvchi hooklaridan chaqiring. Oddiy JavaScript funksiyalari yoki sinf metodlaridan chaqirmang.