Next.js 13 -如何在构建时同时使用userParams和静态预渲染组件从url获取参数

yfjy0ee7  于 2023-06-22  发布在  其他
关注(0)|答案(1)|浏览(539)

我正在学习最新的nextjs 13.4,我已经在路由/notes/[note]上创建了一个页面。现在,我想从URL中获取注解参数,我正在使用import { useParams } from 'next/navigation'
除此之外,我还想静态预渲染这个路径的数据,所以当我构建项目时,这个组件会在.next文件夹中生成它的html文件。为此,我使用generateStaticParams设置预定义的note id(它的工作原理类似于以前的next.js版本中的getStaticPaths)。
现在的问题是,当我离开它作为服务器组件,useParams不工作,并抛出一个错误,当我设置它的客户端组件使用'用户客户端'在顶部,它得到编译,但静态预渲染为给定的4个音符id不工作。

如何使这两种方式都适用于这个组件?

'use client'
import styles from '../../page.module.css'
import { useParams } from 'next/navigation'

async function getNoteData(id : string) {
  const note = await fetch(`https://jsonplaceholder.typicode.com/todos/${id}`);
  if(!note) {
    throw new Error("No data found.");
  }
  return note.json();
}

interface Note {
  userId: string;
  id: number;
  title: string;
  completed: string;
}

export function generateStaticParams() {
  return [{note: '1'}, {note: '2'}, {note: '3'}, {note: '4'}]
}

export default async function Note({params}: {params: {note: string}}) {
  const param = useParams();
  const todo : Note = await getNoteData(param.note);
  return (
    <main className={styles.main}>
      <h1>Note Page</h1>
      <div className={styles.description}>
          <p>{todo?.title}</p>
      </div>
    </main>
  )
}

当我从顶部删除'use client'并从文件中删除userParams时。当我构建项目时,4个html文件成功生成,如下图所示:

pu82cl6c

pu82cl6c1#

你可以试试下面的代码。

**注意:**我没有使用Typescript,因为我已经在JS环境中了。因此,请推断它抱怨的类型。我也选择了ES6。

'use client'
import styles from '../../page.module.css'

// interface Note {
//   userId: string;
//   id: number;
//   title: string;
//   completed: string;
// }

export const generateStaticParams = () => {
    return [{ note: '1' }, { note: '2' }, { note: '3' }, { note: '4' }];
}

export const getNoteData = async (id) => {
    const note = await fetch(`https://jsonplaceholder.typicode.com/todos/${id}`); // it returns a promise;
    const noteData = await note.json();

    if (!noteData) {
        throw new Error("No data found.");
    }
    console.log(noteData) // log it to see what you get

    return noteData;
}

export const Note = async ({ params }) => {
    console.log(params); // log it to see what you get

    const { slug } = params;
    const todo = await getNoteData(slug);

    console.log(todo);  // log it to see if it got here

    // display loader until result comes
    if (!todo) {
        return <p>Loading</p>
    }

    return (
        <main className={styles.main}>
            <h1>Note Page</h1>
            <div className={styles.description}>
                <p>{todo?.title}</p>
            </div>
        </main>
    )
}

export default Note;

更多信息:
https://nextjs.org/docs/app/api-reference/functions/generate-static-params
https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes#generating-static-params

相关问题