使用 ApolloClient 从 graphql 服务器获取数据不起作用。我该如何解决?

Data fetching from graphql server with ApolloClient doesn t work. How can I fix it?

在这里,我使用 graphql 创建新的 ApolloClient

import { ApolloClient, InMemoryCache } from "@apollo/client"

const client = new ApolloClient({
    uri: "http://localhost:4000/graphql",
    cache: new InMemoryCache()
})

export default client

然后我创建一个 ApolloProvider 的上下文

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import {ApolloProvider} from "@apollo/client"
import client from "./common/apollo-client"
import { Provider } from 'react-redux';
import store from "./redux/index"
import { BrowserRouter } from 'react-router-dom';

ReactDOM.render(
  <ApolloProvider client={client}>
    <Provider store={store}>
        <BrowserRouter>
          <App />
        </BrowserRouter>
    </Provider>
  </ApolloProvider>,
  document.getElementById('root')
);

这里是代码中的相同查询

import { gql, useQuery } from "@apollo/client"

const GET_CATEGORIES = gql`
    {
        categories {
            name
        }
    }
`

export default function useGetCategories() {
    const {data} = useQuery(GET_CATEGORIES)
    return data
}

然后我尝试在功能组件中使用这个挂钩,但它记录了 UNDEFINED

export default function Mainpage() {
    const categories = useGetCategories()

    console.log(categories)
    

    return (
        <Header />
    )
}

我试图在 localhost:4000 上重新启动后端,但没有帮助。我该怎么办?

问题在于您使用的是 customHook,这是 graphql 的承诺,它所做的是 return 当前运行时的实例,当时它是未定义的,您所能做的就是简单地使用您想使用的组件为什么要复杂化。

export default function Mainpage() {
    const {loading,data,error} = useQuery(GET_CATEGORIES)
    // first data will be undefined and when the promise resolved it will console data
    console.log(data,{data})
    console.log(loading,{loading})
    console.log(error,{error})
    
    return (
        <Header />
    )
}

但是如果你仍然想为图形使用 customHook,你可以这样做。

  const [getCategories] = useLazyQuery(
    GET_CATEGORIES
  );
  const [data, setData] = useState()

  useEffect(async() => {
    try {
      const res = await getCategories()
      setData(res)
    } catch (err) {
      console.log('error: ', err)
    }
  }, [])

  return data