从 React/Next.js 中的 getInitialProps 重定向
Redirecting from getInitalProps in React/Next.js
我正在使用 React 和 Next.js 并尝试在使用 Router.push('/another-page')
.
无法获得该页面的数据时从该页面重定向用户
为此,我正在检查 getInitalProps
中的状态代码并应用条件。它看起来像这样:
const statusCode = action.currentArticle ? 200 : 404
if (isServer) res.statusCode = statusCode
if (statusCode === 404) {
Router.push('/')
}
状态代码设置正确,它在条件内,此时我收到此错误:No router instance found. You should only use "next/router" inside the client side of your app.
实际上,无论我在组件的生命周期事件中的何处尝试重定向,我都会收到相同的错误,并且在线获得的有关此错误的信息很少。
从 getInitalProps
重定向的模式可以在这个 next.js wiki 中看到:HERE
非常感谢任何有关此错误发生原因或修复方法的想法;)
next/router 在服务器上不可用,这样你会收到一条错误消息,提示找不到路由器,next/router 只能在客户端使用。
要在服务器的 getInitialProps 中重定向用户,您可以使用:
getInitialProps({server,res}){
if(server)
res.redirect('/');
else
Router.push('/');
}
使用 Next.js(以及任何通用的 React 渲染),您的代码在两个不同的环境中执行。首先在 Node(在服务器上)中,然后在浏览器中。 Next 做了一些工作来提供统一的功能 运行 在这两种环境中,但它们非常不同。 Next 不能也不会向您隐瞒。您似乎刚刚在浏览器中加载了一个页面,但这里有更多关于实际情况的详细信息……
上client/browser:
- 在地址栏中输入 url(localhost:3000 或其他),按回车键。
- GET 请求发送到服务器(节点)。
上server/Node:
- GET 请求进来了。
- Node 给你一个请求和一个响应对象。
- 也许你有一些 Express routing/middleware。
- 在某些时候,Next 的
render()
函数被请求和响应对象调用。
- 下一个 运行s
getInitialProps
并传入 request/response.
- React
renderToString()
被调用,它调用以下 React 生命周期方法:
constructor()
componentWillMount()
render()
- React 创建一个 HTML 的字符串发送给客户端。
^ 这是节点。您无法访问 window
,您没有 fetch
,也无法使用 Next Router。这些是浏览器的东西。
返回客户端:
- HTML 已下载并开始渲染。
- HTML 中 js/css 个文件的链接是 downloaded/run。
- 这里包含了Next编译的js代码
- React
render()
是 运行,它将下载的 HTML(DOM)与 React 虚拟 DOM 相关联。以下 React 生命周期方法将 运行:
constructor()
componentWillMount()
render()
componentDidMount()
- 所有其他生命周期方法(更新)将在 props/state 更改时 运行。
^ 这是浏览器。你有 window
,你有 fetch
,你可以使用 Next Router。现在您没有 Node request/response,但这似乎让人们不太感兴趣。
方法和@Shi说的一样,但是getInitialProps中没有server
。取而代之的是,应该检查 window
:
getInitialProps({res}){
if(typeof window === 'undefined')
res.redirect('/');
else
Router.push('/');
}
您可以像这样从 getInitialProps()
重定向:
import Router from 'next/router'
static getInitialProps = (ctx) => {
// On server
if(typeof window === 'undefined'){
res.writeHead(302, {location: '/dashboard'})
res.end()
} else {
// On client
Router.push('/dashboard')
}
return {}
}
我发现这个 https://www.npmjs.com/package/nextjs-redirect 非常简单并且解决了客户端和服务器端的问题。
pages/donate.js
import redirect from 'nextjs-redirect'
export default redirect('https://paypal.me')
为了确保页面永远不会呈现,我们需要添加 await new Promise(() => {})
结束。承诺不需要解决任何问题。
Home.getInitialProps = async ({res}) => {
if(res) {
res.writeHead(302, {location: '/dashboard'});
res.end();
} else {
// window.location.href = '/dashboard';
// Or with SPA redirect
Router.push('/dashboard');
}
await new Promise(() => {});
return {}
}
我正在使用 React 和 Next.js 并尝试在使用 Router.push('/another-page')
.
为此,我正在检查 getInitalProps
中的状态代码并应用条件。它看起来像这样:
const statusCode = action.currentArticle ? 200 : 404
if (isServer) res.statusCode = statusCode
if (statusCode === 404) {
Router.push('/')
}
状态代码设置正确,它在条件内,此时我收到此错误:No router instance found. You should only use "next/router" inside the client side of your app.
实际上,无论我在组件的生命周期事件中的何处尝试重定向,我都会收到相同的错误,并且在线获得的有关此错误的信息很少。
从 getInitalProps
重定向的模式可以在这个 next.js wiki 中看到:HERE
非常感谢任何有关此错误发生原因或修复方法的想法;)
next/router 在服务器上不可用,这样你会收到一条错误消息,提示找不到路由器,next/router 只能在客户端使用。
要在服务器的 getInitialProps 中重定向用户,您可以使用:
getInitialProps({server,res}){
if(server)
res.redirect('/');
else
Router.push('/');
}
使用 Next.js(以及任何通用的 React 渲染),您的代码在两个不同的环境中执行。首先在 Node(在服务器上)中,然后在浏览器中。 Next 做了一些工作来提供统一的功能 运行 在这两种环境中,但它们非常不同。 Next 不能也不会向您隐瞒。您似乎刚刚在浏览器中加载了一个页面,但这里有更多关于实际情况的详细信息……
上client/browser:
- 在地址栏中输入 url(localhost:3000 或其他),按回车键。
- GET 请求发送到服务器(节点)。
上server/Node:
- GET 请求进来了。
- Node 给你一个请求和一个响应对象。
- 也许你有一些 Express routing/middleware。
- 在某些时候,Next 的
render()
函数被请求和响应对象调用。 - 下一个 运行s
getInitialProps
并传入 request/response. - React
renderToString()
被调用,它调用以下 React 生命周期方法:constructor()
componentWillMount()
render()
- React 创建一个 HTML 的字符串发送给客户端。
^ 这是节点。您无法访问 window
,您没有 fetch
,也无法使用 Next Router。这些是浏览器的东西。
返回客户端:
- HTML 已下载并开始渲染。
- HTML 中 js/css 个文件的链接是 downloaded/run。
- 这里包含了Next编译的js代码
- React
render()
是 运行,它将下载的 HTML(DOM)与 React 虚拟 DOM 相关联。以下 React 生命周期方法将 运行:constructor()
componentWillMount()
render()
componentDidMount()
- 所有其他生命周期方法(更新)将在 props/state 更改时 运行。
^ 这是浏览器。你有 window
,你有 fetch
,你可以使用 Next Router。现在您没有 Node request/response,但这似乎让人们不太感兴趣。
方法和@Shi说的一样,但是getInitialProps中没有server
。取而代之的是,应该检查 window
:
getInitialProps({res}){
if(typeof window === 'undefined')
res.redirect('/');
else
Router.push('/');
}
您可以像这样从 getInitialProps()
重定向:
import Router from 'next/router'
static getInitialProps = (ctx) => {
// On server
if(typeof window === 'undefined'){
res.writeHead(302, {location: '/dashboard'})
res.end()
} else {
// On client
Router.push('/dashboard')
}
return {}
}
我发现这个 https://www.npmjs.com/package/nextjs-redirect 非常简单并且解决了客户端和服务器端的问题。
pages/donate.js
import redirect from 'nextjs-redirect'
export default redirect('https://paypal.me')
为了确保页面永远不会呈现,我们需要添加 await new Promise(() => {})
结束。承诺不需要解决任何问题。
Home.getInitialProps = async ({res}) => {
if(res) {
res.writeHead(302, {location: '/dashboard'});
res.end();
} else {
// window.location.href = '/dashboard';
// Or with SPA redirect
Router.push('/dashboard');
}
await new Promise(() => {});
return {}
}