web-dev-qa-db-fra.com

Utilisation de getInitialProps dans Next.js avec TypeScript

D'après la documentation, l'annonce Next.js 5.0 et divers articles sur Internet, il semble que Next.js supporte bien TypeScript et que beaucoup de personnes l'utilisent.

Mais ces discussions suggèrent que getInitialProps, qui est vital pour les applications Next.js, ne fonctionne pas:

Comment puis-je le réparer? À la fois dans ComponentName.getInitialProps = async function() {...} et dans les composants fonctionnels de classe et fonctionnels, l'erreur suivante s'affiche:

[ts] Property 'getInitialProps' does not exist on type '({ data }: { data: any; }) => Element'.
6
lukas

Le moyen classique de résoudre le problème est de déclarer getInitialProps en tant que membre statique:

class MyComponent extends React.Component<{...}, {}> {

  static async getInitialProps(ctx: any) {
    return {...}
  }

  render() {...}

}

Lorsque vous travaillez avec des composants sans état, vous pouvez déclarer une simple extension de React.SFC:

interface StatelessPage<P = {}> extends React.SFC<P> {
  getInitialProps?: (ctx: any) => Promise<P>
}

const MyComponent: StatelessPage<{...}> = (...) => ...

MyComponent.getInitialProps = async (ctx) => {...}
14
Mikael Couzic

Les types de Next.js sont conservés dans le projet DefinitelyTyped , qui possède une nouvelle version 7.0.6.

Pour utiliser les nouveaux types, assurez-vous de les importer dans votre projet:

npm install --save-dev @types/[email protected]

Voici comment vous tapez getInitialProps pour un composant fonctionnel sans état:

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

Voici comment vous tapez getInitialProps pour une classe:

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

Si vous passez en revue les tests dans DefinitelyTyped , vous obtiendrez de nombreuses informations sur la manière d'utiliser d'autres variantes des typages pour Next.

2
Justin Noel