Следующий (хотя и надуманный) компонент нарушает реакции-хуки / правила-хуки (через eslint)

function Apple(props){
  const {seeds} = props;
  if(!seeds){
    return null;
  }
  const [bitesTaken, setBitesTaken] = useState(0);
  return <div>{bitesTaken}</div>
}

Со следующей ошибкой React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?

Я понимаю, что хуки необходимо вызывать в том же порядке, но такого рода условного рендеринга (при условии, что никакие хуки не вызываются до возврата, не препятствует вызову хуков в том же порядке. Я думаю, что правило eslint слишком строгое, но, возможно, есть лучший способ.

Каков наилучший способ условного рендеринга компонента, использующего хуки?

0
Jordan 19 Фев 2020 в 00:38

2 ответа

Лучший ответ

Вы не можете условно использовать крючки, поэтому переместите крюк выше условия.

function Apple(props){
  const {seeds} = props;
  const [bitesTaken, setBitesTaken] = useState(0);
  if(!seeds){
    return null;
  }
  return <div>{bitesTaken}</div>
}

Вы также можете упростить рендеринг следующим образом:

function Apple(props) {
  const { seeds } = props
  const [bitesTaken, setBitesTaken] = useState(0)
  return !!seeds && <div>{bitesTaken}</div>
}

Если seeds равен false, то будет возвращено false (что будет отображаться как ничто), в противном случае будет возвращено div.

Я добавил двойной восклицательный знак в seeds, чтобы превратить его в логическое значение, потому что если seeds равен undefined, то ничего не возвращается из рендера и React выдает ошибку.

3
JMadelaine 18 Фев 2020 в 22:01

Другой вариант - разделить компонент.

import React,{useState} from 'react';

const Apple = (props) => {
    const {seeds} = props;
    return !!seeds && <AppleWithSeeds />;
};

const AppleWithSeeds =(props) => {
    const [bitesTaken] = useState(0);
    return <div>{bitesTaken}</div>
};

export default Apple;

Преимущество этого метода в том, что ваши компоненты остаются маленькими и логичными.

И в вашем случае в инициализаторе useState может быть что-то большее, чем «0», которое вы не хотите ненужного вверху перед условием.

0
BertC 18 Фев 2020 в 22:05