简体   繁体   中英

How to define component instance attributes with ReactJS and Typescript? `Property 'var' does not exist on type 'App'`

For reference, I am using React 16.9.0 and Typescript 3.6.3 .

On this tutorial , they advise to not define instance attributes in my react class:

Just don't. Storing values on the instance of a component is doing this:

 var React = require('react/addons'); class ArbitraryWidget extends React.Component { // ... constructor () { this.derp = 'something'; } handleClick () { this.derp = 'somethingElse'; } render () { var something = this.derp; // ... } } 

This is particularly bad, not only because you're breaking the obvious convention of storing state on this.state, but because render won't automatically trigger when this.derp is updated.

But in my case, my class has attributes which do not affect the state of the Component, then, I can add them as instance attributes without any problem.

But, I was not counting with Typescript bitting in the ass. If you install Create React App and create a Typescript project, you can add the following minimal example to reproduce the problem:

import React from 'react';
import './App.css';

interface AppProps {
}

interface AppState {
}

class App extends React.Component<AppProps, AppState>
{
  constructor(props: AppProps) {
    super(props);

    this.var = 10;
    this.state = {
    };
  }

  render() {
    return (
      <div>
        Hi!
      </div>
    )
  }

}

export default App;

This will cause Typescript to throw the error:

/myfiles/src/App.tsx
TypeScript error in /myfiles/src/App.tsx(15,10):
Property 'var' does not exist on type 'App'.  TS2339

    13 |     super(props);
    14 | 
  > 15 |     this.var = 10;
       |          ^
    16 |     this.state = {
    17 |     };
    18 |   }

Adding either:

interface AppProps {
  var: any;
}

interface AppState {
  var: any;
}

Does not work and Typescript still does not understand that var is an attribute of the component and not an attribute of either this.props or this.state .


Update

As suggested in an answer, I tried this:

private var: number;

But now, Typescript throws another error:

Property 'var' is missing in type '{}' but required in type 'Readonly<AppState>'.  TS2741

    18 | 
    19 |     this.var = 10;
  > 20 |     this.state = {
       |     ^
    21 |     };
    22 |   }
    23 | 

And if I remove the this.state = {} , it still throwing that error:

Property 'var' is missing in type '{}' but required in type 'Readonly<AppProps>'.  TS2741

     5 | import * as serviceWorker from './serviceWorker';
     6 | 
  >  7 | ReactDOM.render(<App />, document.getElementById('root'));
       |                  ^
     8 | 
     9 | // If you want your app to work offline and load faster, you can change
    10 | // unregister() to register() below. Note this comes with some pitfalls.

If var is a property on App , then it's not part of your props or state so adding it to the AppProps or AppState interfaces won't get Typescript to recognise it.

Instead, you should actually define it in your class:

class App extends React.Component<AppProps, AppState>
{
  private var: number;

  constructor(props: AppProps) {
    super(props);

    this.var = 10;
    this.state = {
    };
  }

  render() {
    return (
      <div>
        Hi!
      </div>
    )
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM