nextjs中如何将getStaticProps重构为getServerSideProps
How to refactor getStaticProps to getServerSideProps in nextjs
在下面的代码中
import Head from 'next/head'
import dynamic from 'next/dynamic'
import { AxiosService } from '../../utils/axios-service'
import styles from './[id].module.scss'
import PostSlider from '../../components/postSlider/postSlider'
import SocialMediaButtons from '../../components/socialMediaButtons/socialMediaButtons'
import { getCloundFrontUrl } from '../../utils/common'
const FroalaEditorView: any = dynamic(() => import('react-froala-wysiwyg/FroalaEditorView'), { ssr: false })
export default function Post({ article, posts }) {
const title = article[0].title
const url = article[0].coverImages[0] ? article[0].coverImages[0].url : false
const alt = article[0].coverImages[0] ? article[0].coverImages[0].alternativeText : ''
const content = article[0].content
const date = new Date(article[0].displayDate)
return (
<div id='contentsWrap'>
<Head>
<title>{title}</title>
<meta property="og:image" content={url} />
<meta property="og:title" content={title} />
<meta property="twitter:image:src" content={url} />
<meta property="twitter:title" content={title} />
</Head>
<div className={styles.imgBanner}>
{url && <img src={getCloundFrontUrl(url)} alt={alt} />}
<div>
<h2>NEWS</h2>
<h3>{title}</h3>
<p>{date.getFullYear()}.{date.getMonth() + 1}.{date.getDate()}</p>
</div>
</div>
<div className={`${styles.contentContainer} contentContainer`}>
<FroalaEditorView model={content} />
</div>
<SocialMediaButtons article={article} />
<PostSlider home={false} posts={posts} />
</div>
)
}
export async function getStaticPaths() {
const axios = AxiosService.create()
const res = await axios.get('/archives', {
params: {
category: 'news',
display: true,
showDoson: true,
}
})
const posts = await res.data
// array of routes possible for [id]
const paths = posts.map((post) => `/news/${post.id}`)
// { fallback: false } means routes not inside paths array return 404.
return { paths, fallback: false }
}
export async function getStaticProps({ params }) {
const axios = AxiosService.create()
const resArticle = await axios.get('/archives', {
params: {
category: 'news',
display: true,
showDoson: true,
id: params.id,
}
})
const resPosts = await axios.get('/archives', {
params: {
category: 'news',
display: true,
showDoson: true,
_limit: 5,
_sort: 'id:DESC'
}
})
const article = resArticle.data
return {
props: {
article,
posts: resPosts.data
},
}
}
我正在使用 getStaticProps
从我的 strapi
cms 获取数据。每当 strapi
上发布新文章时,它都应该显示在我的页面上。在我的 localhost
中一切正常,因为在开发(下一个开发)中,每个请求都会调用 getStaticProps
和 getStaticPaths
。
然而在生产中,每当 strapi 创建新文章时,getStaticProps
和 getStaticPaths
不会在构建时调用,因此在下面的代码中
// array of routes possible for [id]
const paths = posts.map((post) => `/news/${post.id}`)
// { fallback: false } means routes not inside paths array return 404.
return { paths, fallback: false }
我在strapi
发表的最新文章id
无法找到,导致生产出现404错误。
如果我提交并推送某些内容,Vercel 将部署我的项目并在构建时调用 getStaticProps
,一切正常。
我认为停止看到此 404 错误的最佳方法是将 getStaticProps
重构为 getServerSideProps
,因为在开发和生产中的每个请求都会调用它。但是我知道我不能将 getStaticPaths
与 getServerSideProps
一起使用。我将如何重构我的代码以使一切正常?
答案出奇的简单
import Head from 'next/head'
import dynamic from 'next/dynamic'
import { AxiosService } from '../../utils/axios-service'
import styles from './[id].module.scss'
import PostSlider from '../../components/postSlider/postSlider'
import SocialMediaButtons from '../../components/socialMediaButtons/socialMediaButtons'
import { getCloundFrontUrl } from '../../utils/common'
const FroalaEditorView: any = dynamic(() => import('react-froala-wysiwyg/FroalaEditorView'), { ssr: false })
export default function Post({ article, posts }) {
const title = article[0].title
// coverImage 없는 경우 페이지 error 발생하지 않고 coverImage 없이 렌더링 함
const url = article[0].coverImages[0] ? article[0].coverImages[0].url : false
const alt = article[0].coverImages[0] ? article[0].coverImages[0].alternativeText : ''
const content = article[0].content
const date = new Date(article[0].displayDate)
return (
<div id='contentsWrap'>
<Head>
<title>{title}</title>
<meta property="og:image" content={url} />
<meta property="og:title" content={title} />
<meta property="twitter:image:src" content={url} />
<meta property="twitter:title" content={title} />
</Head>
<div className={styles.imgBanner}>
{url && <img src={getCloundFrontUrl(url)} alt={alt} />}
<div>
<h2>NEWS</h2>
<h3>{title}</h3>
<p>{date.getFullYear()}.{date.getMonth() + 1}.{date.getDate()}</p>
</div>
</div>
<div className={`${styles.contentContainer} contentContainer`}>
<FroalaEditorView model={content} />
</div>
<SocialMediaButtons article={article} />
<PostSlider home={false} posts={posts} />
</div>
)
}
export async function getServerSideProps({ params }) {
const axios = AxiosService.create()
const resArticle = await axios.get('/archives', {
params: {
category: 'news',
display: true,
showDoson: true,
id: params.id,
}
})
const resPosts = await axios.get('/archives', {
params: {
category: 'news',
display: true,
showDoson: true,
_limit: 5,
_sort: 'id:DESC'
}
})
const article = resArticle.data
return {
props: {
article,
posts: resPosts.data
},
}
}
在下面的代码中
import Head from 'next/head'
import dynamic from 'next/dynamic'
import { AxiosService } from '../../utils/axios-service'
import styles from './[id].module.scss'
import PostSlider from '../../components/postSlider/postSlider'
import SocialMediaButtons from '../../components/socialMediaButtons/socialMediaButtons'
import { getCloundFrontUrl } from '../../utils/common'
const FroalaEditorView: any = dynamic(() => import('react-froala-wysiwyg/FroalaEditorView'), { ssr: false })
export default function Post({ article, posts }) {
const title = article[0].title
const url = article[0].coverImages[0] ? article[0].coverImages[0].url : false
const alt = article[0].coverImages[0] ? article[0].coverImages[0].alternativeText : ''
const content = article[0].content
const date = new Date(article[0].displayDate)
return (
<div id='contentsWrap'>
<Head>
<title>{title}</title>
<meta property="og:image" content={url} />
<meta property="og:title" content={title} />
<meta property="twitter:image:src" content={url} />
<meta property="twitter:title" content={title} />
</Head>
<div className={styles.imgBanner}>
{url && <img src={getCloundFrontUrl(url)} alt={alt} />}
<div>
<h2>NEWS</h2>
<h3>{title}</h3>
<p>{date.getFullYear()}.{date.getMonth() + 1}.{date.getDate()}</p>
</div>
</div>
<div className={`${styles.contentContainer} contentContainer`}>
<FroalaEditorView model={content} />
</div>
<SocialMediaButtons article={article} />
<PostSlider home={false} posts={posts} />
</div>
)
}
export async function getStaticPaths() {
const axios = AxiosService.create()
const res = await axios.get('/archives', {
params: {
category: 'news',
display: true,
showDoson: true,
}
})
const posts = await res.data
// array of routes possible for [id]
const paths = posts.map((post) => `/news/${post.id}`)
// { fallback: false } means routes not inside paths array return 404.
return { paths, fallback: false }
}
export async function getStaticProps({ params }) {
const axios = AxiosService.create()
const resArticle = await axios.get('/archives', {
params: {
category: 'news',
display: true,
showDoson: true,
id: params.id,
}
})
const resPosts = await axios.get('/archives', {
params: {
category: 'news',
display: true,
showDoson: true,
_limit: 5,
_sort: 'id:DESC'
}
})
const article = resArticle.data
return {
props: {
article,
posts: resPosts.data
},
}
}
我正在使用 getStaticProps
从我的 strapi
cms 获取数据。每当 strapi
上发布新文章时,它都应该显示在我的页面上。在我的 localhost
中一切正常,因为在开发(下一个开发)中,每个请求都会调用 getStaticProps
和 getStaticPaths
。
然而在生产中,每当 strapi 创建新文章时,getStaticProps
和 getStaticPaths
不会在构建时调用,因此在下面的代码中
// array of routes possible for [id]
const paths = posts.map((post) => `/news/${post.id}`)
// { fallback: false } means routes not inside paths array return 404.
return { paths, fallback: false }
我在strapi
发表的最新文章id
无法找到,导致生产出现404错误。
如果我提交并推送某些内容,Vercel 将部署我的项目并在构建时调用 getStaticProps
,一切正常。
我认为停止看到此 404 错误的最佳方法是将 getStaticProps
重构为 getServerSideProps
,因为在开发和生产中的每个请求都会调用它。但是我知道我不能将 getStaticPaths
与 getServerSideProps
一起使用。我将如何重构我的代码以使一切正常?
答案出奇的简单
import Head from 'next/head'
import dynamic from 'next/dynamic'
import { AxiosService } from '../../utils/axios-service'
import styles from './[id].module.scss'
import PostSlider from '../../components/postSlider/postSlider'
import SocialMediaButtons from '../../components/socialMediaButtons/socialMediaButtons'
import { getCloundFrontUrl } from '../../utils/common'
const FroalaEditorView: any = dynamic(() => import('react-froala-wysiwyg/FroalaEditorView'), { ssr: false })
export default function Post({ article, posts }) {
const title = article[0].title
// coverImage 없는 경우 페이지 error 발생하지 않고 coverImage 없이 렌더링 함
const url = article[0].coverImages[0] ? article[0].coverImages[0].url : false
const alt = article[0].coverImages[0] ? article[0].coverImages[0].alternativeText : ''
const content = article[0].content
const date = new Date(article[0].displayDate)
return (
<div id='contentsWrap'>
<Head>
<title>{title}</title>
<meta property="og:image" content={url} />
<meta property="og:title" content={title} />
<meta property="twitter:image:src" content={url} />
<meta property="twitter:title" content={title} />
</Head>
<div className={styles.imgBanner}>
{url && <img src={getCloundFrontUrl(url)} alt={alt} />}
<div>
<h2>NEWS</h2>
<h3>{title}</h3>
<p>{date.getFullYear()}.{date.getMonth() + 1}.{date.getDate()}</p>
</div>
</div>
<div className={`${styles.contentContainer} contentContainer`}>
<FroalaEditorView model={content} />
</div>
<SocialMediaButtons article={article} />
<PostSlider home={false} posts={posts} />
</div>
)
}
export async function getServerSideProps({ params }) {
const axios = AxiosService.create()
const resArticle = await axios.get('/archives', {
params: {
category: 'news',
display: true,
showDoson: true,
id: params.id,
}
})
const resPosts = await axios.get('/archives', {
params: {
category: 'news',
display: true,
showDoson: true,
_limit: 5,
_sort: 'id:DESC'
}
})
const article = resArticle.data
return {
props: {
article,
posts: resPosts.data
},
}
}