开发者问题收集

React 错误 - “渲染的钩子比上次渲染时更多。”

2023-02-13
149

我正在开发一个 Raycast 扩展。

在这个函数中,我需要在查询数据库之前创建或更新数据库:

import { useSQL } from "@raycast/utils";

export const useSqlNote = <NoteItem>(query: string) => {
  const [ready, setReady] = useState<boolean>(false);

  let theData: NoteItem[] = [];
  let loadingSelect = true;
  let permissionVw;

  useEffect(() => {
    (async () => {
      await create_or_update_db();
      setReady(true);
    })();
  }, [query]);

  try {
    const { data, isLoading, permissionView } = useSQL<NoteItem>(PATH, query);

    if (ready) {
      theData = data || [];
      loadingSelect = isLoading;
      permissionVw = permissionView;
    }
  } catch (e) {}

  return { data: theData, isLoading: loadingSelect, errorView: permissionVw };
};

当数据库已经创建时,没有 pb。

但是当需要创建数据库时,该过程需要几毫秒——当然,钩子 useSQL 的调用会引发错误,但应该会处理。 但是,我收到了这个错误:

Warning: React has detected a change in the order of Hooks called by Command.
...
Error: Rendered more hooks than during the previous render.

有什么想法可以修复它吗?

1个回答

您没有在组件的顶层调用 useQuery。删除 try catch 块。

要有条件地调用 useQuery 钩子,raycast useQuery 的文档指出,您可以传递带有执行参数的选项以跳过查询的调用。

“options.execute 是一个布尔值,用于指示是否实际执行该函数。这对于函数的参数之一依赖于可能无法立即获得的内容(例如,依赖于某些用户输入)的情况很有用。由于 React 要求在渲染时定义每个钩子,因此此标志使您能够立即定义钩子,但要等到所有参数都准备好后才能执行该函数。”

    const { data, isLoading, permissionView } = useSQL<NoteItem>(PATH, query, {execute: ready});
//You do not need this
//if (ready) {
//      theData = data || [];
//      loadingSelect = isLoading;
//      permissionVw = permissionView;
//    }

  return { data: data || [], isLoading, errorView: permissionView };


SlothOverlord
2023-02-13