React: неправильные примеры вызова хуков внутри циклов и вложенных функций - PullRequest
2 голосов
/ 26 октября 2019

Первое правило хуков - это вызывать хуки только на верхнем уровне, то есть «Не вызывать хуки внутри циклов, условий или вложенных функций». Документы довольно ясно объясняют с помощью примера вызова Hooks внутри условий , но не для двух других случаев: циклов и вложенных функций.

Существуют ли примеры, когда что-то может пойти не так? при вызове хуков внутри циклов и вложенных функций? Более того, не является ли пользовательский хук просто вложенной функцией?

Предоставленные ответы на эти два связанных вопроса здесь и здесь , к сожалению, дают только правильныепримеры.

1 Ответ

2 голосов
/ 26 октября 2019

Пример цикла переменной длины:

const {useState} = React

const WrongLoop = () => {
  const [count, setCount] = useState(1)
  for (let i = 0; i < count; i++) {
    const [x, setX] = useState(i)
  }
  const [unknownOrder, setUnknownOrder] = useState('some state')
  
  return <button onClick={() => setCount(c => c+ 1)}>{count} {unknownOrder}</button>
}

ReactDOM.render(<WrongLoop />, document.getElementById('root'))
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>

Пример вложенной функции, которую будет сложно обнаружить с помощью eslint (особый случай - пользовательские перехватчики - при использовании префикса use... в имени функции этоиспользование в компоненте может быть статически проанализировано eslint):

const {useState} = React

const fn = () => {
  const [x, setX] = useState() // is it OK to use hooks unconditionally here?
}

const WrongFn = () => {
  const [count, setCount] = useState(1)
  if (count === 1) {
    fn() // OK to use normal functions conditionally.. but what if there's a hook inside?
  }
  const [unknownOrder, setUnknownOrder] = useState('some state')
  
  return <button onClick={() => setCount(c => c+ 1)}>{count} {unknownOrder}</button>
}

ReactDOM.render(<WrongFn />, document.getElementById('root'))
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...