Введение

В мире React хуки заняли центральное место, и не зря! React Hooks упрощают логику компонентов, упрощая совместное использование и повторное использование логики с отслеживанием состояния между компонентами. В этой статье мы углубимся в React Hooks, рассмотрим некоторые передовые практики, распространенные ловушки и добавим несколько шуток и GIF-файлов, чтобы держать вас на крючке. Давайте начнем!

  1. useState: сохранение состояния простым

Хук useState позволяет легко добавлять состояние к функциональным компонентам. Он возвращает пару значений: текущее состояние и функцию для его обновления.

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times.</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

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

const [complexState, setComplexState] = useState(() => computeInitialState());

Распространенная ошибка. Не забывайте, что обновление состояния с тем же значением не вызывает повторную визуализацию. Если вы не будете осторожны, вы можете задаться вопросом, почему ваш компонент не обновляется.

2. useEffect: побочные эффекты стали проще

Хук useEffect позволяет вам выполнять побочные эффекты в функциональных компонентах, такие как выборка данных, подписки или ручные манипуляции с DOM.

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

function Example() {
  const [data, setData] = useState([]);

  useEffect(() => {
    fetchData().then((fetchedData) => setData(fetchedData));
  }, []);

  // Render data...
}

Рекомендации. Не забудьте добавить правильные зависимости в массив зависимостей. Если вы этого не сделаете, вы можете получить устаревшие данные или бесконечные циклы.

useEffect(() => {
  // Your effect...
}, [dependency1, dependency2]);

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

3. useCallback: функции запоминания

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

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

function App() {
  const [count, setCount] = useState(0);

  const increment = useCallback(() => {
    setCount((prevCount) => prevCount + 1);
  }, []);

  return (
    <>
      <p>Count: {count}</p>
      <Button onClick={increment}>Increment</Button>
    </>
  );
}

Рекомендации. Используйте useCallback только при необходимости, например, при передаче функции в качестве реквизита дочернему компоненту, использующему React.memo() или PureComponent.

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

4. useContext: делитесь контекстом как профессионал

import React, { useContext } from 'react';
import { ThemeContext } from './ThemeContext';

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

  return <button style={{ background: theme.background, color: theme.foreground }}>Themed button</button>;
}

Рекомендации: useContext следует использовать с одним контекстом для каждого компонента, так как это помогает улучшить читаемость и удобство сопровождения.

Распространенная ошибка. Будьте осторожны при использовании useContext с несколькими контекстами в одном компоненте, так как это может затруднить понимание вашего кода.

5. useReducer: приручение сложной логики состояния

Хук useReducer позволяет вам управлять сложной логикой состояния в ваших компонентах с помощью функции редуктора, аналогичной Redux.

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>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
    </>
  );
}

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

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

Заключение

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

Проверьте мои статьи: