router.isFallback 将 true 更改为 false
router.isFallback changes true to false
我的环境在这里:
Environment
Version
Rails
7.0.0
React
18.0
Next.js
12.1.4
我的getStaticPaths
和getStaticProps
设置在这里:
export const getStaticPaths = async () => {
const data = await axios.get(
`${process.env.NEXT_PUBLIC_ENDPOINT}/admin/users_data`
);
const paths = data.data.users.map((user: any) => {
return { params: { id: user.id.toString() } };
});
return {
paths,
fallback: true,
};
};
export const getStaticProps = async (params: any) => {
const users = params.params.id;
return {
props: { users },
revalidate: 10,
};
};
我要添加用户,next build
后可以访问详情页。
我听说我可以使用 revalidate
和 fallback: true
.
来实现它
没有路径我写了一个错误选项
import ErrorPage from "next/error";
export default function UsersDetailPage(props: {
users: any;
}) {
const router = useRouter();
return !router.isFallback && props.users ? (
// UsersDetailPage
) : (
<ErrorPage statusCode={404} />
);
}
从这段代码直接访问错误的路径,几秒后显示错误页面。
参数是这样的:
props.users: undefined
router.isFallback: true
但之后参数会变成
props.users: example // <-- not existing
router.isFallback: false
并显示详情页。
我不明白这是怎么回事。
你能教我如何解决这个问题吗?
谢谢。
更新
已更新
如果您的路径在 getStaticPaths
中定义但没有来自 API 调用的用户数据,您可以使用 props.user
检查显示 404。使用此解决方案,您可以使用 revalidate: 10
和 fallback: 'blocking'
作为重新验证机制。
import ErrorPage from "next/error";
export default function UsersDetailPage(props: {
users: any;
}) {
if(!props.users) {
return <ErrorPage statusCode={404} />
}
return <UsersDetailPage/>
}
如果您的路径在 build-time 期间未定义,并且您严格阻止用户访问 non-defined 路径的请求,您可以设置 fallback: false
服务 404 而不是您的用户配置文件组件
If fallback is false, then any paths not returned by getStaticPaths will result in a 404 page.
export const getStaticPaths = async () => {
const data = await axios.get(
`${process.env.NEXT_PUBLIC_ENDPOINT}/admin/users_data`
);
const paths = data.data.users.map((user: any) => {
return { params: { id: user.id.toString() } };
});
return {
paths,
fallback: false, //if the path is not defined, we will show 404
};
};
export const getStaticProps = async (params: any) => {
const users = params.params.id;
return {
props: { users },
revalidate: 10,
};
};
旧答案
我认为你误解了 fallback: true
和 fallback: 'blocking'
fallback: true
不会 return 404,但会 return 一个预期的后备页面,并稍后生成 HTML (后续请求将使用新生成的 HTML 而不是备用页面)
The paths that have not been generated at build time will not result in a 404 page.
fallback: 'blocking'
(仅适用于 Next.js 版本 12+)与 revalidate
一起使用。如果您的路径未定义,它将尝试获取数据并且不会 return 后备页面(类似于 server-side 呈现但缓存您的页面供以后使用)
The paths that have not been generated at build time will not result in a 404 page. Instead, Next.js will SSR on the first request and return the generated HTML.
您可以从 Next.js 12
检查 this release note
Currently, Incremental Static Regeneration with fallback: true renders a fallback state before rendering the page contents on the first request to a page that was not generated yet. To block the page from loading (server-rendering), you would need to use fallback: 'blocking'.
您的代码可能如下所示
export const getStaticPaths = async () => {
const data = await axios.get(
`${process.env.NEXT_PUBLIC_ENDPOINT}/admin/users_data`
);
const paths = data.data.users.map((user: any) => {
return { params: { id: user.id.toString() } };
});
return {
paths,
//fallback: true, //serve the fallback page and then generate HTML later
fallback: 'blocking', //fetch data first and generate HTML on the server
};
};
export const getStaticProps = async (params: any) => {
const users = params.params.id;
return {
props: { users },
revalidate: 10,
};
};
首先尝试像这样重构您的代码(假设 getStaticPaths 中的回退设置为 true)
import ErrorPage from "next/error";
export default function UsersDetailPage(props: {
users: any;
}) {
const router = useRouter();
if(router.isFallback){
return <div>Loading...</div>
}
return UsersDetailPage;
如果用户数据尚不可用,则结果 router.isFallback 为真。此后,它将显示 Loading div,直到数据可用为止。如果可行,请将 div 更改为您的 ErrorPage。但我建议向用户展示 加载状态 比 404 页面更好。
文档:https://nextjs.org/docs/api-reference/data-fetching/get-static-paths#fallback-pages
我解决了这个问题。
非常感谢@Nick Vu 和@MLDC。
这对我真的很有帮助。
所有bug的原因都在这里:
export const getStaticProps = async (params: any) => {
const users = params.params.id; // <-- here!!
return {
props: { users },
revalidate: 10,
};
};
似乎 next.js 必须从 getStaticProps 部分的 server-side 获取数据。
所以我固定为:
export const getStaticProps = async (params: any) => {
const data = await axios.get(
`${process.env.NEXT_PUBLIC_ENDPOINT}/admin/user_edit/${params.params.id}`
);
//<-- here!
const users = data.data.user;
return {
props: { users },
revalidate: 10,
};
};
然后问题就解决了
我的环境在这里:
Environment | Version |
---|---|
Rails | 7.0.0 |
React | 18.0 |
Next.js | 12.1.4 |
我的getStaticPaths
和getStaticProps
设置在这里:
export const getStaticPaths = async () => {
const data = await axios.get(
`${process.env.NEXT_PUBLIC_ENDPOINT}/admin/users_data`
);
const paths = data.data.users.map((user: any) => {
return { params: { id: user.id.toString() } };
});
return {
paths,
fallback: true,
};
};
export const getStaticProps = async (params: any) => {
const users = params.params.id;
return {
props: { users },
revalidate: 10,
};
};
我要添加用户,next build
后可以访问详情页。
我听说我可以使用 revalidate
和 fallback: true
.
没有路径我写了一个错误选项
import ErrorPage from "next/error";
export default function UsersDetailPage(props: {
users: any;
}) {
const router = useRouter();
return !router.isFallback && props.users ? (
// UsersDetailPage
) : (
<ErrorPage statusCode={404} />
);
}
从这段代码直接访问错误的路径,几秒后显示错误页面。
参数是这样的:
props.users: undefined
router.isFallback: true
但之后参数会变成
props.users: example // <-- not existing
router.isFallback: false
并显示详情页。
我不明白这是怎么回事。
你能教我如何解决这个问题吗?
谢谢。
更新
已更新
如果您的路径在 getStaticPaths
中定义但没有来自 API 调用的用户数据,您可以使用 props.user
检查显示 404。使用此解决方案,您可以使用 revalidate: 10
和 fallback: 'blocking'
作为重新验证机制。
import ErrorPage from "next/error";
export default function UsersDetailPage(props: {
users: any;
}) {
if(!props.users) {
return <ErrorPage statusCode={404} />
}
return <UsersDetailPage/>
}
如果您的路径在 build-time 期间未定义,并且您严格阻止用户访问 non-defined 路径的请求,您可以设置 fallback: false
服务 404 而不是您的用户配置文件组件
If fallback is false, then any paths not returned by getStaticPaths will result in a 404 page.
export const getStaticPaths = async () => {
const data = await axios.get(
`${process.env.NEXT_PUBLIC_ENDPOINT}/admin/users_data`
);
const paths = data.data.users.map((user: any) => {
return { params: { id: user.id.toString() } };
});
return {
paths,
fallback: false, //if the path is not defined, we will show 404
};
};
export const getStaticProps = async (params: any) => {
const users = params.params.id;
return {
props: { users },
revalidate: 10,
};
};
旧答案
我认为你误解了 fallback: true
和 fallback: 'blocking'
fallback: true
不会 return 404,但会 return 一个预期的后备页面,并稍后生成 HTML (后续请求将使用新生成的 HTML 而不是备用页面)
The paths that have not been generated at build time will not result in a 404 page.
fallback: 'blocking'
(仅适用于 Next.js 版本 12+)与 revalidate
一起使用。如果您的路径未定义,它将尝试获取数据并且不会 return 后备页面(类似于 server-side 呈现但缓存您的页面供以后使用)
The paths that have not been generated at build time will not result in a 404 page. Instead, Next.js will SSR on the first request and return the generated HTML.
您可以从 Next.js 12
检查 this release noteCurrently, Incremental Static Regeneration with fallback: true renders a fallback state before rendering the page contents on the first request to a page that was not generated yet. To block the page from loading (server-rendering), you would need to use fallback: 'blocking'.
您的代码可能如下所示
export const getStaticPaths = async () => {
const data = await axios.get(
`${process.env.NEXT_PUBLIC_ENDPOINT}/admin/users_data`
);
const paths = data.data.users.map((user: any) => {
return { params: { id: user.id.toString() } };
});
return {
paths,
//fallback: true, //serve the fallback page and then generate HTML later
fallback: 'blocking', //fetch data first and generate HTML on the server
};
};
export const getStaticProps = async (params: any) => {
const users = params.params.id;
return {
props: { users },
revalidate: 10,
};
};
首先尝试像这样重构您的代码(假设 getStaticPaths 中的回退设置为 true)
import ErrorPage from "next/error";
export default function UsersDetailPage(props: {
users: any;
}) {
const router = useRouter();
if(router.isFallback){
return <div>Loading...</div>
}
return UsersDetailPage;
如果用户数据尚不可用,则结果 router.isFallback 为真。此后,它将显示 Loading div,直到数据可用为止。如果可行,请将 div 更改为您的 ErrorPage。但我建议向用户展示 加载状态 比 404 页面更好。
文档:https://nextjs.org/docs/api-reference/data-fetching/get-static-paths#fallback-pages
我解决了这个问题。
非常感谢@Nick Vu 和@MLDC。
这对我真的很有帮助。
所有bug的原因都在这里:
export const getStaticProps = async (params: any) => {
const users = params.params.id; // <-- here!!
return {
props: { users },
revalidate: 10,
};
};
似乎 next.js 必须从 getStaticProps 部分的 server-side 获取数据。
所以我固定为:
export const getStaticProps = async (params: any) => {
const data = await axios.get(
`${process.env.NEXT_PUBLIC_ENDPOINT}/admin/user_edit/${params.params.id}`
);
//<-- here!
const users = data.data.user;
return {
props: { users },
revalidate: 10,
};
};
然后问题就解决了