javascript 避免重复的数据库调用,以在下一个13/14中生成元数据

nqwrtyyt  于 12个月前  发布在  Java
关注(0)|答案(1)|浏览(74)

接下来的13和14介绍了generateMetadata函数,作为设置所有页面元数据的推荐方法。
唯一的问题是,由于逻辑被分离,基于后端字段的数据需要进行 * 两次 * 调用,而不是一次。
考虑以下page.tsx

export default async function ProfilePage(props){
    try{
        const profile = await prisma.users.findUnique({
            // ... fetch user data
        });

        return <div>Profile page</div>;
    } catch(err){
        notFound();
    }
}

export async function generateMetadata(params){
    const profile = await prisma.users.findUnique({
        // ... fetch user data
    });

    return {
        title: `${profile.name}'s Profile`,
    };
}

字符串
这需要我获取相同的信息 * 两次 *。
我如何才能在不重复获取的情况下获得相同的结果呢?我想避免使用document.title,因为这会导致在嵌套页面上执行时产生不和谐的体验。

ddarikpa

ddarikpa1#

这样做的唯一问题是--由于逻辑是分离的--基于来自后端的字段的数据需要进行两次调用,而不是一次。

解决方案:

await prisma.users.findUnique写在一个cache() function函数中,该函数被react提供的cache() function Package 在该页面中并从该页面返回数据。然后只需调用该函数const profile = await Function()。由于该函数被缓存并在同一页面上被调用两次,因此NextJS可以防止重复调用。

我做的示例代码: 文件夹结构:*

projectName
├── src
│   └── app
│       ├── api
│       ├── favicon.ico
│       ├── globals.css
│       ├── layout.js
│       └── user
│           ├── page.js
│           └── [id]
│               └── page.js
└── tailwind.config.js

字符串

说明:

  • 有一个页面/user,它显示所有用户,当您单击任何用户时,它会将您带到该页面服务器端的详细信息页面/user/user_id,我们生成元数据并通过调用API将用户数据设置为页面。
  • 有两个调用,一个正在使用缓存,另一个被注解掉了。一次取消注解任何人并查看结果。
    用户页面projectName\src\app\user\page.js(此页面仅拨打电话并获取用户列表)
import Link from "next/link";

const AllUsers = async () => {
    let tmp = await fetch('https://dummyjson.com/users')
    let data = await tmp.json()
    return data.users
}

export default async function Page() {

    let AllUserData = await AllUsers();
    return (
        <div>
            <h1>Users Page</h1>
            <ol>
                {
                    AllUserData.map((u, i) => (
                        <li key={i}>
                            <Link href={'/user/' + u.id}> {u.firstName}</Link>
                        </li>
                    ))
                }
            </ol>
        </div>
    )
}

export async function generateMetadata() {

    let UserDetails = await AllUsers()
    return {
        title: UserDetails.length.toString() + " Users",
    };
}

用户详情页projectName\src\app\user\[id]\page.js

import React from 'react'
import { cache } from 'react'

const GetUserByID = cache(async (ID) => {
    console.log(ID);
    // VISIBLE IN TERMINAL
    console.log("GetUserByID HIT (cached) : ", new Date().toLocaleTimeString());
    let tmp = await fetch('https://dummyjson.com/user/' + ID)
    let data = await tmp.json()
    return data

})

// TO RUN BELOW CODE & COMMENT THE ABOVE CODE
// WITHOUT ANY CACHING , THIS CODE RUNS TWICE

// const GetUserByID = async (ID) => {
//     console.log(ID);
//     console.log("GetUserByID HIT : ", new Date().toLocaleTimeString());
//   // VISIBLE IN TERMINAL

//     let tmp = await fetch('https://dummyjson.com/user/' + ID)
//     let data = await tmp.json()
//     return data
// }

export async function generateMetadata({ params }) {

    let UserDetails = await GetUserByID(params.id)
    return {
        title: UserDetails.firstName + " " + UserDetails.lastName,
    };
}

const UserDetailsPage = async ({ params }) => {
    let UserDetails = await GetUserByID(params.id)
    return (
        <div>
            <h1>UserDetailsPage </h1>
            <p>ID Received from params :{params.id} </p>
            <hr />
            <p>ID from data : {UserDetails.id}</p>
            <p>FirstName : {UserDetails.firstName}</p>
            <p>LastName : {UserDetails.lastName}</p>
            <p>Age : {UserDetails.age}</p>
            <p>Birth Day : {UserDetails.birthDate}</p>
        </div>
    )
}

export default UserDetailsPage

输出:

  • 转到http://localhost:3000/user,此页面的元数据标题设置为从API数据计算的用户数。它将用户显示为链接,单击以查看特定用户详细信息有API 2个调用,一个使用缓存,第二个不使用。
  • 在详细信息页面http://localhost:3000/user/user_id上,在终端中,你会看到缓存 Package 的API调用只执行一次,另一个在未注解时运行两次。
  • 请阅读:*
    *数据获取、缓存和恢复:https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating
    *缓存在Next.jshttps://nextjs.org/docs/app/building-your-application/caching
    ***缓存功能:**https:nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#example
    ***缓存数据:**https:nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#caching-data
    *缓存https://react.dev/reference/react/cache
  • 如果您还有任何疑问,请留下评论(如果需要,我会更新答案)*

相关问题