You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 13+如何获取并渲染数据库数据?

NextJS >=13 数据获取与渲染解决方案

先梳理你代码里的问题

  1. 加了"use client"的客户端组件,不能定义成async function,这是第一个报错的核心原因。
  2. "use server"不能放在客户端组件的内部函数里,这个指令只能用在服务器组件的顶层或单独的服务端函数文件中,客户端组件里用它完全无效还会引发问题。
  3. 默认的服务器组件(无"use client"标识)不能使用useState这类客户端钩子,所以你移除"use client"后会触发第二个错误。

针对不同场景的解决方案

场景1:仅展示数据,无客户端交互(推荐用服务器组件)

服务器组件天然支持async/await,不需要useState和useEffect,直接在组件内获取数据后渲染,全程在服务端完成,性能更优。

// 无需添加"use client",默认是服务器组件
import axios from "axios"

async function ProductsComponent() {
  try {
    const productsresponse = await axios.get(`${process.env.BASE_URL}/api/productControllers`)
    if (productsresponse.status !== 200) {
      console.log("Failed to fetch Products")
      return <div>加载产品失败</div>
    }
    const products = productsresponse.data.message
    
    return (
      <div className="flex flex-col">
        <h3>产品名称</h3>
        {products?.map(product => (
          <div key={product.id}> {/* 必须加key,避免React警告 */}
            <h4>{product?.productName}</h4>
          </div>
        ))}
      </div>
    )
  } catch (error) {
    console.error("获取产品出错:", error)
    return <div>加载产品出错</div>
  }
}

export default ProductsComponent

场景2:需要客户端交互(比如过滤、排序)

这类场景必须用客户端组件(加"use client"),但组件本身不能是异步函数,把数据获取逻辑放在useEffect里的异步函数中执行即可。

"use client"
import axios from "axios"
import { useEffect, useState } from "react"

// 组件是普通函数,不能加async
function ProductsComponent() {
  const [products, setProducts] = useState<any[]>([])
  const [isLoading, setIsLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)

  useEffect(() => {
    const fetchProducts = async () => {
      try {
        const productsresponse = await axios.get(`${process.env.BASE_URL}/api/productControllers`)
        if (productsresponse.status === 200) {
          setProducts(productsresponse.data.message)
        } else {
          setError("获取产品失败")
        }
      } catch (err) {
        setError("获取产品出错")
        console.error(err)
      } finally {
        setIsLoading(false)
      }
    }

    fetchProducts()
  }, [])

  if (isLoading) return <div>正在加载产品...</div>
  if (error) return <div>{error}</div>

  return (
    <div className="flex flex-col">
      <h3>产品名称</h3>
      {products?.map(product => (
        <div key={product.id}>
          <h4>{product?.productName}</h4>
        </div>
      ))}
    </div>
  )
}

export default ProductsComponent

场景3:兼顾服务端预取数据+客户端交互

先在服务器组件里获取数据,再把数据作为props传给客户端组件,这样既享受服务端渲染的性能,又能在客户端处理交互逻辑。

服务器组件(负责取数据):

// 无需"use client",默认服务器组件
import axios from "axios"
import ClientProductsComponent from "./ClientProductsComponent"

async function ProductsComponent() {
  try {
    const productsresponse = await axios.get(`${process.env.BASE_URL}/api/productControllers`)
    if (productsresponse.status !== 200) {
      console.log("Failed to fetch Products")
      return <div>加载产品失败</div>
    }
    const products = productsresponse.data.message
    // 将数据传给客户端组件
    return <ClientProductsComponent products={products} />
  } catch (error) {
    console.error("获取产品出错:", error)
    return <div>加载产品出错</div>
  }
}

export default ProductsComponent

客户端组件(负责交互):

"use client"
import { useState } from "react"

// 定义产品类型,替代any更规范
interface Product {
  id: string
  productName: string
}

function ClientProductsComponent({ products }: { products: Product[] }) {
  const [filteredProducts, setFilteredProducts] = useState(products)

  // 示例:添加产品搜索过滤功能
  const handleSearch = (keyword: string) => {
    const result = products.filter(p => p.productName.includes(keyword))
    setFilteredProducts(result)
  }

  return (
    <div className="flex flex-col">
      <input 
        type="text" 
        placeholder="搜索产品..." 
        onChange={(e) => handleSearch(e.target.value)}
        className="mb-4 p-2 border rounded"
      />
      <h3>产品名称</h3>
      {filteredProducts?.map(product => (
        <div key={product.id} className="mb-2">
          <h4>{product?.productName}</h4>
        </div>
      ))}
    </div>
  )
}

export default ClientProductsComponent

内容的提问来源于stack exchange,提问作者NewJS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 14:07:07