React 查询挂钩在初始加载时未运行

问题描述 投票:0回答:2

这是我的 React 组件。我想要开始工作的钩子是

useGetNotesQuery
。 组件初始加载时,它不会运行。如果我进行选项卡切换或创建新注释,则将调用挂钩并且组件将更新。我对其他钩子没有这个问题,而且我似乎无法弄清楚我做错了什么。我对反应查询还很陌生。我已经验证,当在选项卡开关上调用挂钩或创建新注释时,会传入正确的数据并且挂钩会按预期工作。它只是不会在初始加载时运行。

import React, { useState } from 'react';
import useGetNotesQuery from 'hooks/notes/useNotes';

import { useCreateNote } from 'hooks/notes/useCreateNote';

import Note from './Note';

export default function Notes({ projectItemId, itemId, itemType }: any) {
  const createNote = useCreateNote();

  const {
    data: notes,
    isLoading,
    isError
  } = useGetNotesQuery({ projectItemId, itemId, itemType });
  const [body, setBody] = useState('');

  const createNewNote = async () => {
    await createNote.mutateAsync({
      body,
      projectItemId,
      itemId,
      itemType
    });

    setBody('');
  };

  return (
    <section aria-labelledby="notes-title">
      {!isLoading && (
        <div className="sm:overflow-hidden sm:rounded-lg">
          {console.log(notes)}
          <div className="divide-y divide-gray-200">
            <div className="px-4 py-5 sm:px-6">
              <h2
                id="notes-title"
                className="text-lg font-medium text-gray-900"
              >
                Notes
              </h2>
            </div>
            <div className="px-4 py-6 sm:px-6">
              <ul role="list" className="space-y-8">
                {notes?.map((note) => (
                  <Note key={note.id} note={note} />
                ))}
              </ul>
            </div>
          </div>
          <div className="bg-gray-50 px-4 py-6 sm:px-6">
            <div className="flex space-x-3">
              {/* <div className="flex-shrink-0">
                <img
                  className="h-10 w-10 rounded-full"
                  src={user.imageUrl}
                  alt=""
                />
              </div> */}
              <div className="min-w-0 flex-1">
                <form action="#">
                  <div>
                    <label htmlFor="comment" className="sr-only">
                      About
                    </label>
                    <textarea
                      id="comment"
                      name="comment"
                      rows={3}
                      className="block w-full p-2 rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm text-black"
                      placeholder="Add a note"
                      value={body}
                      onChange={(e) => setBody(e.target.value)}
                    />
                  </div>
                  <div className="mt-3">
                    <button
                      type="submit"
                      onClick={(e) => {
                        e.preventDefault();
                        createNewNote();
                      }}
                      className="inline-flex items-center justify-center rounded-md border border-transparent bg-blue-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
                    >
                      Comment
                    </button>
                  </div>
                </form>
              </div>
            </div>
          </div>
        </div>
      )}
    </section>
  );
}

这是钩子

import { getNotesById } from './../../queries/notes/get-notes';
import { useQuery } from 'react-query';

function useGetNotesQuery({ projectItemId, itemId, itemType }: any) {
  return useQuery('notes', async () => {
    if (projectItemId) {
      return getNotesById({ projectItemId, itemId, itemType }).then(
        (result) => result.data
      );
    }
  });
}

export default useGetNotesQuery;

NextJS 中我的 _app.tsx 文件

import 'styles/main.css';
import 'styles/chrome-bug.css';
import '@/styles/tailwind.css';
import 'katex/dist/katex.css';
import '../styles/globals.css';
import 'react-datepicker/dist/react-datepicker.css';

import { useEffect, useState } from 'react';
import React from 'react';
import { SessionContextProvider } from '@supabase/auth-helpers-react';
import { createBrowserSupabaseClient } from '@supabase/auth-helpers-nextjs';
import { AppProps } from 'next/app';
import { MyUserContextProvider } from 'utils/useUser';
import type { Database } from 'types_db';
import { SidebarProvider } from 'context/SidebarContext';
import { QueryClient, QueryClientProvider } from 'react-query';
// import { ReactQueryDevtools } from 'react-query/devtools';
import { ThemeProvider } from 'next-themes';

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      retry: 3
    }
  }
});

export default function MyApp({ Component, pageProps }: AppProps) {
  const [initialContext, setInitialContext] = useState();
  const [supabaseClient] = useState(() =>
    createBrowserSupabaseClient<Database>()
  );
  useEffect(() => {
    document.body.classList?.remove('loading');
  }, []);

  return (
    <QueryClientProvider client={queryClient}>
      <SessionContextProvider supabaseClient={supabaseClient}>
        <MyUserContextProvider initial={initialContext}>
          <SidebarProvider>
            <ThemeProvider
              attribute="class"
              enableColorScheme={false}
              defaultTheme="light"
            >
              <Component {...pageProps} />
            </ThemeProvider>
            {/* <ReactQueryDevtools initialIsOpen={false} /> */}
          </SidebarProvider>
        </MyUserContextProvider>
      </SessionContextProvider>
    </QueryClientProvider>
  );
}
javascript reactjs react-hooks rendering react-query
2个回答
0
投票

你的另一个胡克返回什么?您的查询

getNotesById
返回
result.data
,但
useQuery
结构需要解析的
result
对象,如下例所示:

const fetchUsers = async () => {
  const res = await fetch("https://jsonplaceholder.typicode.com/users");
  return res.json();
};

const response = useQuery("users", fetchUsers);

0
投票

我来得有点晚了,但我想分享一下我是如何在我的 Next JS 应用程序中“解决”这个问题的,所以希望其他人不必像我一样花费那么长时间。

我尝试过的:

  • 用 api 替换服务器操作并使用 fetch。
  • 各种不同的参数。

我注意到,在生产版本中刷新同一页面效果很好。因此,我尝试在查询中执行服务器操作之前添加延迟,这似乎适用于开发人员模式。

const useMyQuery = () => {
  const {
    data,
    isLoading
  } = useQuery({
    queryKey: ['my-query'],
    queryFn: async () => {
      await new Promise((resolve) => setTimeout(resolve, 1));
      // HACK: this somehow fixes the issue where the query doesn't complete
      return await theServerAction();
    }
  });

  return {
    data,
    isLoading
  };
}
© www.soinside.com 2019 - 2024. All rights reserved.