Ошибка: React Hooks "useState/useEffect/useCallback" are called conditionally

Всем привет! Подскажите, пожалуйста, куда нужно поместить условие c list.length, чтобы убрать ошибку React Hooks are called conditionally? Пробовал в useEffect обернуть, но в таком случае возвращается пустой список при первом рендере. Важно, чтобы список всё также возвращался при первом рендере

const List = ({ list }) => {
  if (list.length === 0) {
    return <div>LOADING...</div>;
  }

  const [localList, setLocalList] = useState(list);

  useEffect(() => {
    setList(localList);
  }, [localList]);

  const handleChange = useCallback((id) => {
    setLocalList((prevLocalList) =>
      prevLocalList.map((item, index) => {
        return index !== id ? item : { ...item, checked: !item.checked };
      })
    );
  }, []);

  return (
    <>
      {localList?.map((item, index) => (
        <MemoRow key={index} {...item} handleChange={handleChange} />
      ))}
    </>
  );
};

Ответы (2 шт):

Автор решения: entithat

Пересуньте if после вызова всех хуков.

const List = ({ list }) => {
  

  const [localList, setLocalList] = useState(list);

  useEffect(() => {
    setList(localList);
  }, [localList]);

  const handleChange = useCallback((id) => {
    setLocalList((prevLocalList) =>
      prevLocalList.map((item, index) => {
        return index !== id ? item : { ...item, checked: !item.checked };
      })
    );
  }, []);

  if (list.length === 0) {
    return <div>LOADING...</div>;
  }

  return (
    <>
      {localList?.map((item, index) => (
        <MemoRow key={index} {...item} handleChange={handleChange} />
      ))}
    </>
  );
};
→ Ссылка
Автор решения: mondevyat

Отрефакторил код следующим образом:

const List = ({ list }) => {
  const [localList, setLocalList] = useState(list);

  useEffect(() => {
    if (localList.length === 0) {
      setLocalList(list);
    }
  }, [list, setLocalList, localList]);

  useEffect(() => {
    setList(localList);
  }, [localList]);

  const handleChange = useCallback((id) => {
    setLocalList((prevLocalList) =>
      prevLocalList.map((item, index) => {
        return index !== id ? item : { ...item, checked: !item.checked };
      })
    );
  }, []);

  return list.length === 0 ? (
    <div>LOADING...</div>
  ) : (
    <>
      {localList?.map((item, index) => (
        <MemoRow key={index} {...item} handleChange={handleChange} />
      ))}
    </>
  );
};
→ Ссылка