React Hooks: głębokie cięcia PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

React Hooks: głębokie cięcia

Hooki to funkcje wielokrotnego użytku. Pozwalają ci używać były i inne funkcje (np. metody cyklu życia itd.) bez pisania klasy. Funkcje przechwytujące pozwalają nam „zahaczyć się” w Cykl życia stanu reakcji używanie komponentów funkcjonalnych, co pozwala nam manipulować stanem naszych komponentów funkcjonalnych bez konieczności konwertowania ich na komponenty klas.

React wprowadzone haki w wersji 16.8 i od tego czasu dodaje więcej. Niektóre są bardziej używane i popularne niż inne, na przykład useEffect, useState, useContext haki. Nie mam wątpliwości, że sięgałeś po nie, jeśli pracujesz z Reactem.

Ale mnie interesują mniej znane haki React. Chociaż wszystkie haczyki Reacta są interesujące na swój sposób, jest ich pięć, które naprawdę chcę wam pokazać, ponieważ mogą nie pojawiać się w codziennej pracy — a może tak, a znajomość ich daje dodatkowe supermoce.

Spis treści

useReducer

Połączenia useReducer hook to narzędzie do zarządzania stanem, podobnie jak inne hooki. W szczególności jest to alternatywa dla useState hak.

Jeśli używasz useReducer zaczep, aby zmienić dwa lub więcej stanów (lub akcji), nie będziesz musiał manipulować tymi stanami indywidualnie. Hak śledzi wszystkie stany i wspólnie nimi zarządza. Innymi słowy: zarządza i ponownie renderuje zmiany stanu. w przeciwieństwie do useState hak, useReducer jest łatwiejsze, jeśli chodzi o obsługę wielu stanów w złożonych projektach.

Przypadków użycia

useReducer może pomóc w zmniejszeniu złożoności pracy z wieloma stanami. Użyj go, gdy okaże się, że musisz zbiorczo śledzić wiele stanów, ponieważ pozwala traktować zarządzanie stanami i logikę renderowania komponentu jako oddzielne kwestie.

Składnia

useReducer akceptuje trzy argumenty, z których jeden jest opcjonalny:

  • funkcja reduktora
  • initialState
  • an init funkcja (opcjonalnie)
const [state, dispatch] = useReducer(reducer, initialState)
const [state, dispatch] = useReducer(reducer, initialState initFunction) // in the case where you initialize with the optional 3rd argument

Przykład

Poniższy przykład to interfejs zawierający dane wejściowe, licznik i przycisk. Interakcja z każdym elementem aktualizuje stan. Zauważ jak useReducer pozwala nam zdefiniować wiele spraw jednocześnie, zamiast konfigurować je indywidualnie.

import { useReducer } from 'react';
const reducer = (state, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { ...state, count: state.count + 1 };
    case 'DECREMENT':
      return { ...state, count: state.count - 1 };
    case 'USER_INPUT':
      return { ...state, userInput: action.payload };
    case 'TOGGLE_COLOR':
      return { ...state, color: !state.color };
    default:
      throw new Error();
  }
}

function App() {
  const [state, dispatch] = useReducer(reducer, { count: 0, userInput: '', color: false })

  return (
    <main className="App, App-header" style={{ color: state.color ? '#000' : '#FF07FF'}}>
      <input style={{margin: '2rem'}}
        type="text"
        value={state.userInput}
        onChange={(e) => dispatch({ type: 'USER_INPUT', payload: e.target.value })}
      />
      <br /><br />
      <p style={{margin: '2rem'}} >{state.count}</p>
      <section style={{margin: '2rem'}}>
        <button  onClick={(() => dispatch({ type: 'DECREMENT' }))}>-</button>
        <button onClick={(() => dispatch({ type: 'INCREMENT' }))}>+</button>
        <button onClick={(() => dispatch({ type: 'TOGGLE_COLOR' }))}>Color</button>
      </section>
      <br /><br />
      <p style={{margin: '2rem'}}>{state.userInput}</p>
    </main>
  );
}
export default App;

Z powyższego kodu zauważyłem, jak jesteśmy w stanie łatwo zarządzać kilkoma stanami w reduktor (przypadek przełącznika), to pokazuje korzyści z useReducer. Jest to moc, jaką daje podczas pracy w złożonych aplikacjach z wieloma stanami.

useRef

Połączenia useRef hook służy do tworzenia referencji na elementach w celu uzyskania dostępu do DOM. Ale co więcej, zwraca obiekt z .current właściwość, która może być używana przez cały cykl życia składnika, umożliwiając zachowanie danych bez powodowania ponownego renderowania. Więc useRef wartość pozostaje taka sama między renderowaniami; aktualizacja odniesienia nie powoduje ponownego renderowania.

Przypadków użycia

Sięgnij po useRef zaczepić, gdy chcesz:

  • Manipuluj DOM za pomocą przechowywanych informacji mutowalnych.
  • Dostęp do informacji z komponentów podrzędnych (elementów zagnieżdżonych).
  • Ustaw ostrość na elemencie.

Jest to najbardziej przydatne podczas przechowywania zmiennych danych w aplikacji bez powodowania ponownego renderowania.

Składnia

useRef akceptuje tylko jeden argument, którym jest wartość początkowa.

const newRefComponent = useRef(initialValue);

Przykład

Tutaj użyłem useRef i useState hook, aby pokazać, ile razy aplikacja renderuje zaktualizowany stan podczas wpisywania tekstu.

import './App.css'

function App() {
  const [anyInput, setAnyInput] = useState(" ");
  const showRender = useRef(0);
  const randomInput = useRef();
  const toggleChange = (e) => {
    setAnyInput (e.target.value);
    showRender.current++;
  
  }
  const focusRandomInput = () => {
    randomInput.current.focus();
  }

  return (
    <div className="App">
      <input className="TextBox" 
        ref ={randomInput} type="text" value={anyInput} onChange={toggleChange}
      />
      <h3>Amount Of Renders: {showRender.current}</h3>
      <button onClick={focusRandomInput}>Click To Focus On Input </button>
    </div>
  );
}

export default App;

Zwróć uwagę, jak wpisanie każdego znaku w polu tekstowym aktualizuje stan aplikacji, ale nigdy nie powoduje pełnego ponownego renderowania.

useImperativeHandle

Wiesz, w jaki sposób komponent potomny ma dostęp do funkcji wywoływania przekazywanych im z komponentu nadrzędnego? Rodzice przekazują je za pomocą rekwizytów, ale to przekazywanie jest „jednokierunkowe” w tym sensie, że rodzic nie jest w stanie wywołać funkcji, która jest w dziecku.

Cóż, useImperativeHandle umożliwia rodzicowi dostęp do funkcji komponentu potomnego.

Jak to działa?

  • Funkcja jest zdefiniowana w komponencie potomnym.
  • A ref jest dodawany w rodzicu.
  • Używamy pliki forwardRef, zezwalając na ref który został określony jako przekazany dziecku.
  • useImperativeHandle eksponuje funkcje dziecka poprzez ref.

Przypadków użycia

useImperativeHandle działa dobrze, gdy chcesz, aby zmiany w składniku nadrzędnym miały wpływ na komponent nadrzędny. Tak więc takie rzeczy jak zmiana ostrości, zwiększanie i zmniejszanie oraz rozmyte elementy mogą być sytuacjami, w których sięgasz po ten hak, aby rodzic mógł zostać odpowiednio zaktualizowany.

Składnia

useImperativeHandle (ref, createHandle, [dependencies])

Przykład

W tym przykładzie mamy dwa przyciski, jeden w komponencie nadrzędnym, a drugi w potomnym. Kliknięcie przycisku rodzica pobiera dane od dziecka, co pozwala nam manipulować komponentem rodzica. Jest skonfigurowany tak, że kliknięcie przycisku dziecka nie przekazuje niczego z komponentu rodzica do dziecka, aby pomóc zilustrować, w jaki sposób przekazujemy rzeczy w przeciwnym kierunku.

// Parent component
import React, { useRef } from "react";
import ChildComponent from "./childComponent";
import './App.css';

function useImperativeHandle() {
  const controlRef = useRef(null);
  return (
    onClick={
      () => {
        controlRef.current.controlPrint();
      }
    }
    >
    Parent Box
  );
}
export default useImperativeHandle;
// Child component
import React, { forwardRef, useImperativeHandle, useState } from "react";

const ChildComponent = forwardRef((props, ref) => {
  const [print, setPrint] = useState(false);
  useImperativeHandle(ref, () => ({
    controlPrint() 
    { setPrint(!print); },
  })
  );

  return (
    <>
    Child Box
    { print && I am from the child component }
  );
});

export default ChildComponent;

Wydajność

useMemo

useMemo to jeden z najmniej używanych, ale najciekawszych hooków Reacta. Może poprawić wydajność i zmniejszyć opóźnienia, szczególnie w przypadku dużych obliczeń w Twojej aplikacji. Jak to? Za każdym razem, gdy stan komponentu aktualizuje się i komponenty są ponownie renderowane, useMemo hook zapobiega konieczności ponownego obliczania przez Reacta wartości.

Widzisz, funkcje reagują na zmiany stanu. The useMemo hak przejmuje funkcję i zwraca wartość zwracaną tej funkcji. Buforuje tę wartość, aby zapobiec dodatkowym nakładom pracy na ponowne jej renderowanie, a następnie zwraca ją, gdy zmieni się jedna z zależności.

Ten proces jest wywoływany zapamiętywanie i to pomaga zwiększyć wydajność, pamiętając wartość z poprzedniego żądania, aby można było jej użyć ponownie bez powtarzania całej tej matematyki.

Przypadków użycia

Najlepszymi przypadkami użycia będą za każdym razem, gdy pracujesz z ciężkimi obliczeniami, w których chcesz przechowywać wartość i używać jej przy kolejnych zmianach stanu. Może to być niezła poprawa wydajności, ale zbyt częste jej używanie może mieć dokładnie odwrotny skutek, ponieważ zabiera pamięć aplikacji.

Składnia

useMemo( () => 
  { // Code goes here },
  []
)

Przykład

Po kliknięciu przycisku ten miniprogram wskazuje, kiedy liczba jest parzysta lub nieparzysta, a następnie podnosi wartość do kwadratu. Dodałem wiele zer do pętli, aby zwiększyć jej moc obliczeniową. Zwraca wartość w rozlanych sekundach i nadal działa dobrze ze względu na useMemo hak.

// UseMemo.js
import React, { useState, useMemo } from 'react'

function Memo() {
  const [memoOne, setMemoOne] = useState(0);
  const incrementMemoOne = () => { setMemoOne(memoOne + 1) }
  const isEven = useMemo(() => { 
    let i = 0 while (i < 2000000000) i++ return memoOne % 2 === 0
  },
  [memoOne]);
  
  const square = useMemo(()=> { 
    console.log("squared the number"); for(var i=0; i < 200000000; i++);
    return memoOne * memoOne;
  },
  [memoOne]);

  return (
    Memo One - 
    { memoOne }
    { isEven ? 'Even' : 'Odd' } { square } 
  );
}
export default Memo

Wydajność

useMemo jest trochę jak ten useCallback hak, ale różnica polega na tym useMemo może przechowywać zapamiętaną wartość z funkcji, gdzie useCallback przechowuje samą zapamiętaną funkcję.

useCallback

Połączenia useCallback hak jest kolejnym interesującym, a ostatnia sekcja była rodzajem ostrzeżenia spoilera na temat tego, co robi.

Jak właśnie widzieliśmy, useCallback działa jak useMemo zahaczają o to, że oboje używają zapamiętywania do buforowania czegoś do późniejszego użycia. Podczas gdy useMemo przechowuje obliczenia funkcji jako wartość w pamięci podręcznej, useCallback przechowuje i zwraca funkcję.

Przypadków użycia

Jak useMemo, useCallback jest fajną optymalizacją wydajności, ponieważ przechowuje i zwraca zapamiętane wywołanie zwrotne i wszelkie jego zależności bez ponownego renderowania.

Składnia

const getMemoizedCallback = useCallback (
  () => { doSomething () }, []
);

Przykład


{ useCallback, useState } from "react";
import CallbackChild from "./UseCallback-Child";
import "./App.css"

export default function App() {
  const [toggle, setToggle] = useState(false);
  const [data, setData] = useState("I am a data that would not change at every render, thanks to the useCallback");
  const returnFunction = useCallback(
    (name) => 
    { return data + name; }, [data]
  );
  return (
    onClick={() => {
      setToggle(!toggle);
    }}
    >
    {" "}

    // Click To Toggle
    { toggle && h1. Toggling me no longer affects any function } 
  ); 
}
// The Child component
import React, { useEffect } from "react";

function CallbackChild(
  { returnFunction }
) {
  useEffect(() => 
    { console.log("FUNCTION WAS CALLED"); },
    [returnFunction]);
  return { returnFunction(" Hook!") };
}
export default CallbackChild;

Wydajność

Końcowe przemyślenia

No to jedziemy! Właśnie spojrzeliśmy na pięć super poręcznych haczyków React, które moim zdaniem często są pomijane. Podobnie jak w przypadku wielu takich łapanek, po prostu drapiemy powierzchnię tych haków. Każdy z nich ma swoje własne niuanse i względy, które należy wziąć pod uwagę podczas ich używania. Ale miejmy nadzieję, że masz dobre ogólne pojęcie o tym, czym one są i kiedy mogą być lepiej dopasowane niż inny haczyk, po który możesz sięgać częściej.

Najlepszym sposobem na ich pełne zrozumienie jest praktyka. Zachęcam więc do przećwiczenia używania tych haczyków w swojej aplikacji, aby lepiej zrozumieć. W tym celu możesz uzyskać bardziej szczegółowe informacje, sprawdzając następujące zasoby:

Znak czasu:

Więcej z Sztuczki CSS