Skip to content

react: unable to use getSnapshotBeforeUpdate #24820

@jacobwgillespie

Description

@jacobwgillespie

I seem to be unable to use components that define getSnapshotBeforeUpdate, one of the new React lifecycle methods. The DefinitelyTyped tests pass because they only define the method, but the error comes when you attempt to actually use the defined component. The error looks like:

repo version

import * as React from 'react'

interface Props {
  number: number
}

interface Snapshot {
  number: number
}

class Demo extends React.Component<Props, {}, Snapshot> {
  getSnapshotBeforeUpdate() {
    return {number: 321}
  }

  componentDidUpdate(_prevProps: Props, _prevState: {}, snapshot?: Snapshot) {
    console.log(snapshot)
  }

  render() {
    return <strong>{this.props.number}</strong>
  }
}

export class App extends React.Component {
  render() {
    // ERROR HERE:
    return <Demo number={123} />
  }
}
src/index.tsx:30:12 - error TS2605: JSX element type 'Demo' is not a constructor function for JSX elements.
  Types of property 'getSnapshotBeforeUpdate' are incompatible.
    Type '() => { number: number; }' is not assignable to type '((prevProps: Readonly<any>, prevState: Readonly<{}>) => null) | undefined'.
      Type '() => { number: number; }' is not assignable to type '(prevProps: Readonly<any>, prevState: Readonly<{}>) => null'.
        Type '{ number: number; }' is not assignable to type 'null'.

Here is a repo that reproduces this issue: https://github.com/jacobwgillespie/typescript-react-reproduction. This is using React v16.3.1, TypeScript v2.8.1, and @types/react v16.3.5.

It appears that TypeScript thinks that the getSnapshotBeforeUpdate method must always return null. I do not understand why this is happening from looking at the code, and especially given that the getSnapshotBeforeUpdate method is typed via the type defs (returning an invalid snapshot does cause an error).

/cc @Kovensky @johnnyreilly


Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions