如何在动态路由中使用 getStaticPaths 和 getStaticProps 获取下一个身份验证会话?
How do I get the next-auth session with getStaticPaths and getStaticProps in dynamic routing?
我正在尝试在 NextJS 应用程序中实现动态路由。我需要来自 next-auth 的令牌,以通过对 API 的 axios 请求从 getReport 和 getReports(在 /reports.js 中)获取数据,但我不知道如何获取它。当我使用 [itemId].js 中硬编码的令牌尝试时它起作用了,所以路由工作正常(我认为)。
由于 getStaticPaths 和 getStaticProps 在服务器上运行,我尝试使用 getSession(),但我不确定它是否不起作用或者我没有正确使用它,但我始终无法获得会话。使用 getSession() 对我来说是更好的选择。
我也试过保存在localStorage中,但是getStaticProps无法访问localStorage。
我正在考虑使用 Redux,但我真的很想避免它。
这是我的代码:
/pages/user/reports/[reportId]/[itemId].js
import { useSession } from "next-auth/react";
import { useLayoutEffect } from "react";
import Loading from "../../../../components/Loading";
import Layout from "../../../../components/user/layout/Layout";
import { getAllReportsIds, getReportItem } from "../../../../components/user/reports";
const token = 'here is currently the token'
export default function Report({ reportItem }) {
return (
<Layout>
{/* Start Page Header */}
<div className="page-header">
<h1 className="title">{ reportItem.name }</h1>
<ol className="breadcrumb">
<li className="active">{ reportItem.description }</li>
</ol>
</div>
{/* End Page Header */}
{/* START CONTAINER */}
<div className="container-padding">
{/* Start Row */}
<div className="row">
{/* Start Panel */}
<div className="col-md-12">
<div className="panel panel-default">
<div className="panel-body">
<div className="embed-responsive embed-responsive-16by9">
<iframe title="Reporte" className="embed-responsive-item" src={reportItem.code} allowFullScreen></iframe>
</div>
</div>
</div>
</div>
{/* End Panel */}
</div>
{/* End Row */}
</div>
{/* END CONTAINER */}
</Layout>
)
}
export async function getStaticPaths() {
const paths = await getAllReportsIds(token)
return {
paths,
fallback: false
}
}
export async function getStaticProps(context) {
console.log('context en static props: ', context)
try {
const reportItem = await getReportItem(token, context.params.reportId, context.params.itemId)
return {
props : {
reportItem
}
}
} catch(error) {
console.log('error: ', error)
return {
props : {
error: true
}
}
}
}
/components/user/reports.js
import { getReport, getReports } from "../../pages/api/axios/reports";
export async function getAllReportsIds(token) {
try {
const { data } = await getReports(token)
let reportIds = []
reportIds = data.flatMap(report => {
return (
report.report_items.map(item => {
return {
params: {
reportId: JSON.stringify(report.id),
itemId: JSON.stringify(item.id)
}
}
})
)
})
return reportIds
} catch(error) {
console.log('error: ', error)
}
}
export async function getReportItem(token, reportId, itemId) {
try {
const { data } = await getReport(token, reportId)
let reportItem = {}
data.report_items.map(item => {
if (JSON.stringify(item.id) === itemId) {
reportItem = item
}
})
return reportItem
} catch(error) {
console.log('error: ', error)
}
}
如果有人能提供帮助,将不胜感激。
出于某种原因,我认为我需要使用 getStaticPaths,但我是从 context.params 获取路径的,所以我通过删除该函数并使用 getServerSideProps(如提到的 Mentlegen)解决了这个问题。
export async function getServerSideProps(context) {
const session = await getSession(context)
try {
const reportItem = await getReportItem(session.token, context.params.reportId, context.params.itemId)
return {
props : {
reportItem
}
}
} catch(error) {
console.log('error: ', error)
return {
props : {
error: true
}
}
}
}
我正在尝试在 NextJS 应用程序中实现动态路由。我需要来自 next-auth 的令牌,以通过对 API 的 axios 请求从 getReport 和 getReports(在 /reports.js 中)获取数据,但我不知道如何获取它。当我使用 [itemId].js 中硬编码的令牌尝试时它起作用了,所以路由工作正常(我认为)。
由于 getStaticPaths 和 getStaticProps 在服务器上运行,我尝试使用 getSession(),但我不确定它是否不起作用或者我没有正确使用它,但我始终无法获得会话。使用 getSession() 对我来说是更好的选择。
我也试过保存在localStorage中,但是getStaticProps无法访问localStorage。
我正在考虑使用 Redux,但我真的很想避免它。
这是我的代码:
/pages/user/reports/[reportId]/[itemId].js
import { useSession } from "next-auth/react";
import { useLayoutEffect } from "react";
import Loading from "../../../../components/Loading";
import Layout from "../../../../components/user/layout/Layout";
import { getAllReportsIds, getReportItem } from "../../../../components/user/reports";
const token = 'here is currently the token'
export default function Report({ reportItem }) {
return (
<Layout>
{/* Start Page Header */}
<div className="page-header">
<h1 className="title">{ reportItem.name }</h1>
<ol className="breadcrumb">
<li className="active">{ reportItem.description }</li>
</ol>
</div>
{/* End Page Header */}
{/* START CONTAINER */}
<div className="container-padding">
{/* Start Row */}
<div className="row">
{/* Start Panel */}
<div className="col-md-12">
<div className="panel panel-default">
<div className="panel-body">
<div className="embed-responsive embed-responsive-16by9">
<iframe title="Reporte" className="embed-responsive-item" src={reportItem.code} allowFullScreen></iframe>
</div>
</div>
</div>
</div>
{/* End Panel */}
</div>
{/* End Row */}
</div>
{/* END CONTAINER */}
</Layout>
)
}
export async function getStaticPaths() {
const paths = await getAllReportsIds(token)
return {
paths,
fallback: false
}
}
export async function getStaticProps(context) {
console.log('context en static props: ', context)
try {
const reportItem = await getReportItem(token, context.params.reportId, context.params.itemId)
return {
props : {
reportItem
}
}
} catch(error) {
console.log('error: ', error)
return {
props : {
error: true
}
}
}
}
/components/user/reports.js
import { getReport, getReports } from "../../pages/api/axios/reports";
export async function getAllReportsIds(token) {
try {
const { data } = await getReports(token)
let reportIds = []
reportIds = data.flatMap(report => {
return (
report.report_items.map(item => {
return {
params: {
reportId: JSON.stringify(report.id),
itemId: JSON.stringify(item.id)
}
}
})
)
})
return reportIds
} catch(error) {
console.log('error: ', error)
}
}
export async function getReportItem(token, reportId, itemId) {
try {
const { data } = await getReport(token, reportId)
let reportItem = {}
data.report_items.map(item => {
if (JSON.stringify(item.id) === itemId) {
reportItem = item
}
})
return reportItem
} catch(error) {
console.log('error: ', error)
}
}
如果有人能提供帮助,将不胜感激。
出于某种原因,我认为我需要使用 getStaticPaths,但我是从 context.params 获取路径的,所以我通过删除该函数并使用 getServerSideProps(如提到的 Mentlegen)解决了这个问题。
export async function getServerSideProps(context) {
const session = await getSession(context)
try {
const reportItem = await getReportItem(session.token, context.params.reportId, context.params.itemId)
return {
props : {
reportItem
}
}
} catch(error) {
console.log('error: ', error)
return {
props : {
error: true
}
}
}
}