React Hooks: глубокий подход к разведке данных PlatoBlockchain. Вертикальный поиск. Ай.

React Hooks: глубокие порезы

Хуки — это многократно используемые функции. Они позволяют использовать состояние и другие функции (например, методы жизненного цикла и т. д.) без написания класса. Хуки-функции позволяют нам «подцепиться» за Жизненный цикл состояния реакции используя функциональные компоненты, что позволяет нам управлять состоянием наших функциональных компонентов без необходимости преобразовывать их в компоненты класса.

реагировать введены крючки еще в версии 16.8 и с тех пор добавляется больше. Некоторые из них более используются и популярны, чем другие, например useEffect, useStateи useContext крючки. Я не сомневаюсь, что вы достигли их, если работаете с React.

Но что меня интересует, так это менее известные хуки React. Хотя все хуки React интересны по-своему, есть пять из них, которые я действительно хочу показать вам, потому что они могут не всплывать в вашей повседневной работе — или, может быть, они появляются, и знание их дает вам некоторые дополнительные сверхспособности.

Содержание

useReducer

Ассоциация useReducer hook — это инструмент управления состоянием, как и другие хуки. В частности, это альтернатива useState крюк.

Если вы используете useReducer hook для изменения двух или более состояний (или действий), вам не придется манипулировать этими состояниями по отдельности. Хук отслеживает все состояния и коллективно управляет ими. Другими словами: он управляет и повторно отображает изменения состояния. в отличие от useState крючок useReducer проще, когда дело доходит до обработки многих состояний в сложных проектах.

Use cases

useReducer может помочь уменьшить сложность работы с несколькими состояниями. Используйте его, когда вам нужно отслеживать несколько состояний вместе, так как это позволяет вам рассматривать управление состоянием и логику рендеринга компонента как отдельные задачи.

Синтаксис

useReducer принимает три аргумента, один из которых является необязательным:

  • функция редуктора
  • initialState
  • an init функция (опционально)
const [state, dispatch] = useReducer(reducer, initialState)
const [state, dispatch] = useReducer(reducer, initialState initFunction) // in the case where you initialize with the optional 3rd argument

Пример

В следующем примере показан интерфейс, содержащий текстовый ввод, счетчик и кнопку. Взаимодействие с каждым элементом обновляет состояние. Обратите внимание, как useReducer позволяет нам определять несколько случаев одновременно, а не настраивать их по отдельности.

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;

Из приведенного выше кода видно, как мы можем легко управлять несколькими состояниями в редуктор (переключатель), это показывает преимущество useReducer. Это сила, которую он дает при работе со сложными приложениями с несколькими состояниями.

useRef

Ассоциация useRef ловушка используется для создания ссылок на элементы для доступа к DOM. Но более того, он возвращает объект с .current свойство, которое можно использовать на протяжении всего жизненного цикла компонента, позволяя данным сохраняться, не вызывая повторного рендеринга. Итак useRef значение остается неизменным между рендерами; обновление ссылки не вызывает повторный рендеринг.

Use cases

Дотянись до useRef крючок, когда вы хотите:

  • Манипулируйте DOM с сохраненной изменяемой информацией.
  • Доступ к информации из дочерних компонентов (вложенных элементов).
  • Установить фокус на элемент.

Это наиболее полезно при хранении изменяемых данных в вашем приложении без повторного рендеринга.

Синтаксис

useRef принимает только один аргумент, который является Начальное значение.

const newRefComponent = useRef(initialValue);

Пример

Здесь я использовал useRef и useState ловушка, чтобы показать, сколько раз приложение отображает обновленное состояние при вводе текста.

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;

Обратите внимание, что ввод каждого символа в текстовом поле обновляет состояние приложения, но никогда не приводит к полному повторному рендерингу.

useImperativeHandle

Вы знаете, как дочерний компонент получает доступ к функциям вызова, переданным им от родительского компонента? Родители передают их через свойства, но эта передача является «однонаправленной» в том смысле, что родитель не может вызвать функцию, которая находится в дочернем элементе.

Что ж, useImperativeHandle позволяет родителю получить доступ к функциям дочернего компонента.

Как это работает?

  • Функция определена в дочернем компоненте.
  • A ref добавляется в родителя.
  • МЫ ИСПОЛЬЗУЕМ forwardRef, позволяя ref который был определен для передачи ребенку.
  • useImperativeHandle раскрывает функции ребенка через ref.

Use cases

useImperativeHandle хорошо работает, когда вы хотите, чтобы на родительский компонент влияли изменения в дочернем компоненте. Таким образом, такие вещи, как изменение фокуса, увеличение и уменьшение, а также размытие элементов, могут быть ситуациями, когда вы обнаружите, что тянетесь к этому крючку, чтобы родитель мог быть соответствующим образом обновлен.

Синтаксис

useImperativeHandle (ref, createHandle, [dependencies])

Пример

В этом примере у нас есть две кнопки, одна в родительском компоненте, а другая в дочернем. Нажатие на родительскую кнопку извлекает данные из дочернего элемента, позволяя нам манипулировать родительским компонентом. Он настроен таким образом, что при нажатии на дочернюю кнопку ничего не передается от родительского компонента к дочернему, чтобы помочь проиллюстрировать, как мы передаем вещи в противоположном направлении.

// 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;

Результат

useMemo

useMemo — один из наименее используемых, но самых интересных хуков React. Это может повысить производительность и уменьшить задержку, особенно при больших вычислениях в вашем приложении. Как так? Каждый раз, когда состояние компонента обновляется и компоненты перерисовываются, useMemo hook не позволяет React пересчитывать значения.

Видите ли, функции реагируют на изменения состояния. useMemo крючок принимает функцию и возвращает возвращаемое значение этой функции. Он кэширует это значение, чтобы не тратить дополнительные усилия на его повторный рендеринг, а затем возвращает его, когда одна из зависимостей изменилась.

Этот процесс называется мемоизации и это то, что помогает повысить производительность за счет запоминания значения из предыдущего запроса, чтобы его можно было использовать снова, не повторяя всю эту математику.

Use cases

Наилучшие варианты использования будут в любое время, когда вы работаете с тяжелыми вычислениями, где вы хотите сохранить значение и использовать его при последующих изменениях состояния. Это может быть хорошим выигрышем в производительности, но слишком частое его использование может иметь прямо противоположный эффект, перегружая память вашего приложения.

Синтаксис

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

Пример

При нажатии кнопки эта мини-программа указывает, является ли число четным или нечетным, а затем возводит значение в квадрат. Я добавил много нулей в цикл, чтобы увеличить его вычислительную мощность. Он возвращает значение в потерянных секундах и по-прежнему хорошо работает из-за useMemo крюк.

// 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

Результат

useMemo немного похоже на useCallback крючок, но разница в том, что useMemo может хранить запомненное значение из функции, где useCallback сохраняет саму запомненную функцию.

useCallback

Ассоциация useCallback hook — еще один интересный момент, а последний раздел был чем-то вроде предупреждения о том, что он делает.

Как мы только что видели, useCallback работает как useMemo зацепка в том, что они оба используют мемоизацию для кэширования чего-либо для последующего использования. Пока useMemo сохраняет вычисление функции как кэшированное значение, useCallback сохраняет и возвращает функцию.

Use cases

Подобно useMemo, useCallback является хорошей оптимизацией производительности, поскольку он сохраняет и возвращает запомненный обратный вызов и любые его зависимости без повторного рендеринга.

Синтаксис

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

Пример


{ 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;

Результат

Заключение

Ну вот! Мы только что рассмотрели пять очень удобных хуков React, которые, как мне кажется, часто упускают из виду. Как и во многих подобных обзорах, мы просто царапаем поверхность этих крючков. У каждого из них есть свои нюансы и соображения, которые следует учитывать при их использовании. Но, надеюсь, у вас есть хорошее общее представление о том, что они из себя представляют и когда они могут подойти лучше, чем другой крючок, к которому вы можете чаще обращаться.

Лучший способ полностью понять их — это практика. Поэтому я рекомендую вам попрактиковаться в использовании этих хуков в вашем приложении для лучшего понимания. Для этого вы можете получить более подробную информацию, просмотрев следующие ресурсы:

Отметка времени:

Больше от CSS хитрости