Spec-Zone.ru › React 18

Правила использования хуков

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

  • Вызывать хуки только на верхнем уровне
  • Вызывать хуки только из функций React

Вызывать хуки только на верхнем уровне

Функции, имена которых начинаются с use , в React называются хуками.

Не вызывайте хуки внутри циклов, условий, вложенных функций или блоков try/catch/finally. Вместо этого всегда используйте хуки на верхнем уровне вашей функции React, перед любыми ранними возвратами. Вы можете вызывать хуки только во время отрисовки компонента функции React:

  • ✅ Вызывайте их на верхнем уровне в теле компонента-функции.
  • ✅ Вызывайте их на верхнем уровне в теле собственного хука.
function Counter() {
  // ✅ Good: top-level in a function component
  const [count, setCount] = useState(0);
  // ...
}

function useWindowWidth() {
  // ✅ Good: top-level in a custom Hook
  const [width, setWidth] = useState(window.innerWidth);
  // ...
}

Нельзя вызывать хуки (функции, начинающиеся с use) в других случаях, например:

  • 🔴 Не вызывайте хуки внутри условий или циклов.
  • 🔴 Не вызывайте хуки после условного return оператора.
  • 🔴 Не вызывайте хуки в обработчиках событий.
  • 🔴 Не вызывайте хуки в компонентах класса.
  • 🔴 Не вызывайте хуки внутри функций, передаваемых в useMemo, useReducer, или useEffect.
  • 🔴 Не вызывайте хуки внутри блоков try/catch/finally.

Если вы нарушите эти правила, вы можете увидеть эту ошибку.

function Bad({ cond }) {
  if (cond) {
    // 🔴 Bad: inside a condition (to fix, move it outside!)
    const theme = useContext(ThemeContext);
  }
  // ...
}

function Bad() {
  for (let i = 0; i < 10; i++) {
    // 🔴 Bad: inside a loop (to fix, move it outside!)
    const theme = useContext(ThemeContext);
  }
  // ...
}

function Bad({ cond }) {
  if (cond) {
    return;
  }
  // 🔴 Bad: after a conditional return (to fix, move it before the return!)
  const theme = useContext(ThemeContext);
  // ...
}

function Bad() {
  function handleClick() {
    // 🔴 Bad: inside an event handler (to fix, move it outside!)
    const theme = useContext(ThemeContext);
  }
  // ...
}

function Bad() {
  const style = useMemo(() => {
    // 🔴 Bad: inside useMemo (to fix, move it outside!)
    const theme = useContext(ThemeContext);
    return createStyle(theme);
  });
  // ...
}

class Bad extends React.Component {
  render() {
    // 🔴 Bad: inside a class component (to fix, write a function component instead of a class!)
    useEffect(() => {})
    // ...
  }
}

function Bad() {
  try {
    // 🔴 Bad: inside try/catch/finally block (to fix, move it outside!)
    const [x, setX] = useState(0);
  } catch {
    const [x, setX] = useState(1);
  }
}

Вы можете использовать eslint-plugin-react-hooks плагин для выявления таких ошибок.

Примечание

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


Вызывать хуки только из функций React

Не вызывайте хуки из обычных функций JavaScript. Вместо этого вы можете:

✅ Вызывать хуки из компонентов-функций React. ✅ Вызывать хуки из собственных хуков.

Следуя этому правилу, вы обеспечиваете, что вся логика состояния в компоненте явно видна из исходного кода.

function FriendList() {
  const [onlineStatus, setOnlineStatus] = useOnlineStatus(); // ✅
}

function setOnlineStatus() { // ❌ Not a component or custom Hook!
  const [onlineStatus, setOnlineStatus] = useOnlineStatus();
}

© 2013–present Facebook Inc.
Licensed under the Creative Commons Attribution 4.0 International Public License.
https://react.dev/reference/rules/rules-of-hooks

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API