[英]Pass prop to every single page in Next.js with getInitialProps using Typescript
[英]Using getInitialProps in Next.js with TypeScript
從文檔來看,Next.js 5.0 公告和互聯網上的各種文章似乎 Next.js 很好地支持 TypeScript 並且很多人都在使用它。
但是這些線程表明getInitialProps
對 Next.js 應用程序至關重要,它不起作用:
我該如何解決? 在 class 和功能組件中,當我執行ComponentName.getInitialProps = async function() {...}
時,我收到以下錯誤:
[ts] Property 'getInitialProps' does not exist on type '({ data }: { data: any; }) => Element'.
有關使用新類型和命名導出鍵入數據獲取方法的當前建議,請參閱Next.js 文檔。
tl;博士:
import { GetStaticProps, GetStaticPaths, GetServerSideProps } from 'next'
export const getStaticProps: GetStaticProps = async (context) => {
// ...
}
export const getStaticPaths: GetStaticPaths = async () => {
// ...
}
export const getServerSideProps: GetServerSideProps = async (context) => {
// ...
}
以上答案已過時,因為 Next.js 現在正式支持 TypeScript( 此處公告)
此版本的一部分是更好的 TypeScript 類型,其中大部分 Next.js 都是用 TypeScript 本身編寫的。 這意味着@types/next
包將被棄用,取而代之的是官方 Next.js 類型。
相反,您應該導入NextPage
類型並將其分配給您的組件。 您還可以使用NextPageContext
類型鍵入getInitialProps
。
import { NextPage, NextPageContext } from 'next';
const MyComponent: NextPage<MyPropsInterface> = props => (
// ...
)
interface Context extends NextPageContext {
// any modifications to the default context, e.g. query types
}
MyComponent.getInitialProps = async (ctx: Context) => {
// ...
return props
}
編輯:自 Next 9 發布以來,此答案已過時。請參閱上面的答案。
解決問題的經典方法是將getInitialProps
聲明為靜態成員:
class MyComponent extends React.Component<{...}, {}> {
static async getInitialProps(ctx: any) {
return {...}
}
render() {...}
}
使用無狀態組件時,您可以聲明React.SFC
的簡單擴展:
interface StatelessPage<P = {}> extends React.SFC<P> {
getInitialProps?: (ctx: any) => Promise<P>
}
const MyComponent: StatelessPage<{...}> = (...) => ...
MyComponent.getInitialProps = async (ctx) => {...}
Next.js 的類型在有新版本 7.0.6 的絕對類型項目中維護。
為了使用新類型,請確保在項目中導入它們:
npm install --save-dev @types/next@7.0.6
以下是為無狀態功能組件鍵入getInitialProps
的方法:
import { NextFunctionComponent, NextContext } from 'next'
// Define what an individual item looks like
interface IDataObject {
id: number,
name: string
}
// Define the props that getInitialProps will inject into the component
interface IListComponentProps {
items: IDataObject[]
}
const List: NextFunctionComponent<IListComponentProps> = ({ items }) => (
<ul>
{items.map((item) => (
<li key={item.id}>
{item.id} -- {item.name}
</li>
))}
</ul>
)
List.getInitialProps = async ({ pathname }: NextContext) => {
const dataArray: IDataObject[] =
[{ id: 101, name: 'larry' }, { id: 102, name: 'sam' }, { id: 103, name: 'jill' }, { id: 104, name: pathname }]
return { items: dataArray }
}
export default List
以下是為類鍵入getInitialProps
的方法:
import React from 'react'
import { NextContext } from 'next'
// Define what an individual item looks like
interface IDataObject {
id: number,
name: string
}
// Define the props that getInitialProps will inject into the component
interface IListClassProps {
items: IDataObject[]
}
class List extends React.Component<IListClassProps> {
static async getInitialProps({ pathname }: NextContext) {
const dataArray: IDataObject[] =
[{ id: 101, name: 'larry' }, { id: 102, name: 'sam' }, { id: 103, name: 'jill' }, { id: 104, name: pathname }]
return { items: dataArray }
}
render() {
return (
<ul>
{this.props.items.map((item) => (
<li key={item.id}>
{item.id} -- {item.name}
</li>
))}
</ul>
)
}
}
export default List
如果您查看DescribeTyped 中的測試,您可以獲得很多關於如何使用 Next 類型的其他變體的見解。
按照文檔
import React from 'react'
import { NextPageContext } from 'next'
interface Props {
userAgent?: string;
}
export default class Page extends React.Component<Props> {
static async getInitialProps({ req }: NextPageContext) {
const userAgent = req ? req.headers['user-agent'] : navigator.userAgent
return { userAgent }
}
render() {
const { userAgent } = this.props
return <main>Your user agent: {userAgent}</main>
}
}
簡單的解決方案是聲明類型:
declare global {
namespace React {
interface FunctionComponent<P = {}> {
getInitialProps(): void;
}}}
如果您使用 TypeScript,您可以對 function 組件使用 NextPage 類型
它不是一個真正的解決方案,但可能的解決方法是僅將TypeScript用於服務器端和通用腳本(.ts擴展名)。
對於React組件,請使用.jsx擴展名並放棄TypeScript。 prop-types
和prop-types-exact
- 它們為props提供類型檢查(使用npm
安裝包)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.