Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly set initial state in React with Typescript without constructor?

In modern JS, we can directly set an initial state for a React component like this:

class App extends React.Component {
  state = {value: 10}

  render() {
    return <div>{this.state.value}</div>
  }
}

When I am trying to do this with Typescript, TSLint says "The class property 'state' must be marked either 'private', 'public', or 'protected'". If I set it to "private", the linter will report Class 'App' incorrectly extends base class 'Component<{}, { value: number; }, any>'. Property 'state' is private in type 'App' but not in type 'Component<{}, { value: number; }, any>'. on App. I am aware that I can tweak the linter rules to skip this kind of checks, but checking the visibility of class properties in general is a good thing I want to utilize.

After testing out all three options, only choosing "public" won't get TSLint throw out errors. But since the state here represents the internal state of this specific component, setting it to public seems pretty weird. Am I doing it the correct way?

class App extends React.Component<{}, { value: number }> {
  public state = { value: 10 };

  public render() {
    return <div>{this.state.value}</div>;
  }
}

In all TS-React tutorials I've found online, a constructor is used, like in the old JS syntax.

class App extends React.Component<{}, { value: number }> {
  constructor(props: any) {
    super(props);
    this.state = { value: 10 };
  }

  public render() {
    return <div>{this.state.value}</div>;
  }
}

Is setting class property directly considered a bad practice/style in Typescript?

like image 722
John Avatar asked Oct 10 '18 20:10

John


People also ask

How would you define a state in React without a constructor?

Initialize State Without Constructor Another way of initializing state in React is to use the Class property. Once the class is instantiated in the memory all the properties of the class are created so that we can read these properties in the render function.

Can we use state without constructor in React?

You can also use state in React function components (without a constructor), but using higher-order components or render prop components.

How can state be used without constructor?

React State without a Constructor There you can set initial state in the constructor of the class, but also access and update it with this. state and this. setState , because you have access to the class instance by using the this object.

How do you set state to initial state in React?

To reset a component to its initial state: When an event occurs, call the setState() function, passing it the initial state.


1 Answers

Am I doing it the correct way?

Yes.

Is setting class property directly considered a bad style in Typescript?

No.

A slightly better approach

Consider declaring state as public readonly, and using the Readonly modifier.

This will satisfy TSLint while also giving you some protection against being modified incorrectly (ie. not using this.setState). Even though state is still exposed to the outside, this is never usually a problem.

interface IState {
  value: number;
}

class App extends React.Component<{}, IState> {
  public readonly state: Readonly<IState> = {
    value: 10
  }

  public render() {
    return <div>{this.state.value}</div>
  }
}

The TSLint rule

Declaring access modifiers explicitly is a good thing, even if it results in the same access implicitly. It helps keep your code clear, so I wouldn't disable this TSLint rule.

like image 102
rshepp Avatar answered Nov 04 '22 14:11

rshepp