Next.js:如何使用GraphQL和无头CMS(graphCMS)进行客户端数据获取。

huangapple go评论63阅读模式
英文:

Next.js: How to do client-side data fetching with grapql and headless CMS (graphCMS)

问题

I'm currently facing an issue with fetching data in a client-side component using Next.js app dir, and I'm hoping to get some assistance with resolving it.

我目前正在面临一个问题,即在客户端组件中使用 Next.js 应用目录 获取数据,希望能获得一些解决方案的帮助。

I have a specific requirement where I need to fetch data with graphql from graphCMS within a client-side component in Next.js. However, I'm unsure of the best approach to accomplish this. I have attempted a few different methods, but none of them seem to be working as expected.

我有一个具体的要求,需要在 Next.js 中的客户端组件中使用 GraphQL 从 graphCMS 获取数据。但是,我不确定如何最好地实现这一目标。我尝试了几种不同的方法,但似乎都没有按预期工作。

Here's a simplified version of my component code:

这是我的组件代码的简化版本:

This graphql request is located in a different file (index.js)
这个 GraphQL 请求位于不同的文件中(index.js

export async function getAllPosts() {
  const query = gql`
    query Posts {
      articles {
        id
        title
        excerpt
      }
    }
  `;
  const result = await request(graphqlAPI, query);
  return result.articles;
};

From my Home component, I am trying to get the data from getAllPosta() as follow. But in the console it ends in an boring infinite loop.

从我的 Home 组件中,我尝试使用以下方式获取数据,但在控制台中它会陷入一个无聊的无限循环中。

'use client'
import { useEffect, useState } from "react";

export default Home(){
  const [data, setData] = useState([])

  useEffect(() => {
    getAllPosts().then((result) => {
      setData(result);
    });
  })

  return (
    data.map(post => {
      <div key={post.id}>
        <h1>{post.title}</h1>
        <p>{post.excerpt}</p>
      </div>
    })
  )
}

Thank you

英文:

I'm currently facing an issue with fetching data in a client-side component using Next.js app dir, and I'm hoping to get some assistance with resolving it.

I have a specific requirement where I need to fetch data with graphql from graphCMS within a client-side component in Next.js. However, I'm unsure of the best approach to accomplish this. I have attempted a few different methods, but none of them seem to be working as expected.

Here's a simplified version of my component code:

This graphql request is located in a different file (index.js)

export async function getAllPosts() {
  const query = gql`
    query Posts {
      articles {
        id
        title
        excerpt
      }
    }
  `;
  const result = await request(graphqlAPI, query);
  return result.articles;
};

From my Home component, I am trying to get the data from getAllPosta() as follow. But in the console it ends in an boring infinite loop.

&#39;use client&#39;
import { useEffect, useState } from &quot;react&quot;;

export default Home(){
  const [data, setData] = useState([])

  useEffect(() =&gt; {
    getAllPosts().then((result) =&gt; {
      setData(result);
    });
  })

  return (
    data.map(post =&gt; {
      &lt;div key={post.id}&gt;
        &lt;h1&gt;{post.title}&lt;/h1&gt;
        &lt;p&gt;{post.excerpt}&lt;/p&gt;
      &lt;/div&gt;
    })
  )
}

Thank you

答案1

得分: 1

假设你的代码的这个简化版本接近实际实现,我会说你的问题出在 useEffect 上。你没有提供一个依赖数组,因此 useEffect 会在每次渲染时运行,因为它使用 setData(result) 更新了你的组件状态,这将触发一次渲染,导致 useEffect(...) 再次运行,从而产生无限循环。如果你只需要获取数据一次,只需在依赖项中添加 []。你的代码应该像这样:

'使用客户端'
import { useEffect, useState } from "react";

export default function Home(){
  const [data, setData] = useState([])

  useEffect(() => {
    getAllPosts().then((result) => {
      setData(result);
    });
  }, []) // <-- 注意这里的 '[]'

  return (
    data.map(post => (
      <div key={post.id}>
        <h1>{post.title}</h1>
        <p>{post.excerpt}</p>
      </div>
    ))
  )
}
英文:

Assuming this simplified version of your code is close to the real implementation I would say that your problem is with useEffect. You don't have a dependency array so useEffect runs on every render, since it updates your component state with setData(result), it will trigger a render causing useEffect(...) to run again and hence an infinite loop. If you only need to fetch the data once you just need to add [] to the dependencies. Your code should be something like this:

&#39;use client&#39;
import { useEffect, useState } from &quot;react&quot;;

export default function Home(){
  const [data, setData] = useState([])

  useEffect(() =&gt; {
    getAllPosts().then((result) =&gt; {
      setData(result);
    });
  }, []) // &lt;-- note the &#39;[]&#39; here
 
  return (
    data.map(post =&gt; {
      &lt;div key={post.id}&gt;
        &lt;h1&gt;{post.title}&lt;/h1&gt;
        &lt;p&gt;{post.excerpt}&lt;/p&gt;
      &lt;/div&gt;
    })
  )
}

huangapple
  • 本文由 发表于 2023年6月29日 22:40:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76582122.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定