动态路由问题-Next.js(以及typescript)



我是next.js的新手,我正在尝试使用生成此路由**pages/perfil/[name]**

主要的问题是,在那个页面中,我使用的来自API调用的数据是基于id的,但我不希望id出现在路由中,我希望名称出现在那里。

让我告诉你我是怎么做到的

这就是界面的样子,这样你就可以理解数据

export type userFriends = {
_id?: string;
name?: string;
perfil?: string;
identifier?: string;
notification?: boolean;
friend?: boolean;
createdAt?: string;
};
export type user = {
_id?: string;
name?: string;
email?: string;
password?: string;
friends?: userFriends[];
banner?: string;
perfil?: string;
};
export interface IuserData {
data: user;
}
export type multipleUsers = { data: user[] };

这里的逻辑是

export const getStaticPaths: GetStaticPaths = async () => {
const { data }: multipleUsers = await axios.get(
"http://localhost:5000/api/user"
);
const paths = data.map(path => {
return { params: { name: path.name, id: path._id } };
});
return { paths, fallback: true };
};
export const getStaticProps: GetStaticProps = async ({ params }) => {
const { data }: IuserData = await axios.get(
`http://localhost:5000/api/user/singleU/${params.id}`
);
return {
props: { data }
};
};

只有当我放[id]而不是[name]时,路由才有效,正如你所看到的,我在params中有name和id。

next.js一直抛出这个错误

Error: Request failed with status code 500
at createError (C:Usersdiego cifuentesDesktopPortafolioFullstack ProjectsFacebook - MERN ( with next.js )frontednode_modulesaxioslibcorecreateError.js:16:15)
at settle (C:Usersdiego cifuentesDesktopPortafolioFullstack ProjectsFacebook - MERN ( with next.js )frontednode_modulesaxioslibcoresettle.js:17:12)
at IncomingMessage.handleStreamEnd (C:Usersdiego cifuentesDesktopPortafolioFullstack ProjectsFacebook - MERN ( with next.js )frontednode_modulesaxioslibadaptershttp.js:260:11)
at IncomingMessage.emit (events.js:327:22)
at endReadableNT (internal/streams/readable.js:1327:12)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
config: {
url: 'http://localhost:5000/api/user/singleU/undefined',
method: 'get',
headers: {
Accept: 'application/json, text/plain, */*',
'User-Agent': 'axios/0.21.1'
},
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
adapter: [Function: httpAdapter],
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
validateStatus: [Function: validateStatus],
data: undefined
},
request: <ref *1> ClientRequest {
_events: [Object: null prototype] {
socket: [Function (anonymous)],
abort: [Function (anonymous)],
aborted: [Function (anonymous)],
connect: [Function (anonymous)],
error: [Function (anonymous)],
timeout: [Function (anonymous)],
prefinish: [Function: requestOnPrefinish]
},
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: true,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: Socket {
connecting: false,
_hadError: false,
_parent: null,
_host: 'localhost',
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 6,
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
parser: null,
_httpMessage: [Circular *1],
[Symbol(async_id_symbol)]: 662958,
[Symbol(kHandle)]: null,
[Symbol(kSetNoDelay)]: false,
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kBytesRead)]: 294,
[Symbol(kBytesWritten)]: 154,
[Symbol(RequestTimeout)]: undefined
},
_header: 'GET /api/user/singleU/undefined HTTP/1.1rn' +
'Accept: application/json, text/plain, */*rn' +
'User-Agent: axios/0.21.1rn' +
'Host: localhost:5000rn' +
'Connection: closern' +
'rn',
_keepAliveTimeout: 0,
_onPendingData: [Function: noopPendingOutput],
agent: Agent {
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
defaultPort: 80,
protocol: 'http:',
options: [Object],
requests: {},
sockets: {},
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
scheduling: 'fifo',
maxTotalSockets: Infinity,
totalSocketCount: 0,
[Symbol(kCapture)]: false
},
socketPath: undefined,
method: 'GET',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
path: '/api/user/singleU/undefined',
_ended: true,
res: IncomingMessage {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 3,
_maxListeners: undefined,
socket: [Socket],
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
headers: [Object],
rawHeaders: [Array],
trailers: {},
rawTrailers: [],
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 500,
statusMessage: 'Internal Server Error',
client: [Socket],
_consuming: false,
_dumped: false,
req: [Circular *1],
responseUrl: 'http://localhost:5000/api/user/singleU/undefined',
redirects: [],
[Symbol(kCapture)]: false,
[Symbol(RequestTimeout)]: undefined
},
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: 'localhost',
protocol: 'http:',
_redirectable: Writable {
_writableState: [WritableState],
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
_options: [Object],
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 0,
_requestBodyBuffers: [],
_onNativeResponse: [Function (anonymous)],
_currentRequest: [Circular *1],
_currentUrl: 'http://localhost:5000/api/user/singleU/undefined',
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype] {
accept: [Array],
'user-agent': [Array],
host: [Array]
}
},
response: {
status: 500,
statusText: 'Internal Server Error',
headers: {
'x-powered-by': 'Express',
'access-control-allow-origin': '*',
'content-type': 'application/json; charset=utf-8',
'content-length': '36',
etag: 'W/"24-z7bS9qns7nLyRRBbZiCqtiTHQlM"',
date: 'Mon, 14 Jun 2021 22:20:50 GMT',
connection: 'close'
},
config: {
url: 'http://localhost:5000/api/user/singleU/undefined',
method: 'get',
headers: [Object],
transformRequest: [Array],
transformResponse: [Array],
timeout: 0,
adapter: [Function: httpAdapter],
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
validateStatus: [Function: validateStatus],
data: undefined
},
request: <ref *1> ClientRequest {
_events: [Object: null prototype],
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: true,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [Socket],
_header: 'GET /api/user/singleU/undefined HTTP/1.1rn' +
'Accept: application/json, text/plain, */*rn' +
'User-Agent: axios/0.21.1rn' +
'Host: localhost:5000rn' +
'Connection: closern' +
'rn',
_keepAliveTimeout: 0,
_onPendingData: [Function: noopPendingOutput],
agent: [Agent],
socketPath: undefined,
method: 'GET',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
path: '/api/user/singleU/undefined',
_ended: true,
res: [IncomingMessage],
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: 'localhost',
protocol: 'http:',
_redirectable: [Writable],
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype]
},
data: { Error: 'API request went wrong !' }
},
isAxiosError: true,
toJSON: [Function: toJSON]
}

我能做什么?

谢谢你抽出时间!

getStaticPaths用于在静态生成站点时填充给定动态路由的潜在参数。传递给getStaticPropsparams值将是在路由中传递的参数。没有";隐藏的";路由参数。

您可以使用的一种方法是存储用户参数,以便在静态站点生成期间,getStaticProps可以引用以前在运行getStaticPaths:时提取的数据

const memoize = fn => {
let promise, result;
return () => {
if (result) {
return result;
} else if (promise) {
return promise;
} else {
promise = fn();
try {
result = await promise;
return result;
} finally {
promise = null; // avoid leak
}
}
}
}
const getUserLookup = memoize(async () => {
const { data }: allUsers = await axios.get(
"http://localhost:5000/api/user"
);
userIdLookup = new Map(
data.map(({ _id, name}) => [name, _id])
);
return userIdLookup;
});
export const getStaticPaths: GetStaticPaths = async () => {
const userNameIds = await getUserLookup();
return {
paths: [...userNameIds.entries()].map(([name, id]) => ({ name, id })),
fallback: true
};
};
export const getStaticProps: GetStaticProps = async ({ params }) => {
const lookup = await getUserLookup();
const { data }: IuserData = await axios.get(
`http://localhost:5000/api/user/singleU/${lookup.get(params.name)}`
);
return {
props: { data }
};
};

因为静态站点的构建是在同一个过程中运行的,并且应该只为所有用户运行一次,所以这应该避免多次获取用户。

相关内容

最新更新