4

I am a novice in ReactJS. Was watching a tutorial that is recorded in ES6 JavaScript and simultaneously I am trying to recreate the same app in TypeScript (I am a novice in TypeScript too!!). In ES6 we need to use a class based approach if that particular component needs to maintain it's own state. I have installed "babel-plugin-transform-class-properties" so i do set state in ES6 as export default class SomeClass { state = { someProperty : someValue }}. But in TypeScript I am using class based approach for every component. So here is a component that tries to maintain it's own state:

import React from 'react';

interface IAddOptionProps {
    handleAddOption: (option: string) => string |null;
};

interface IAddOptionState {
    error: any;
};

export default class AddOption extends React.Component<IAddOptionProps, IAddOptionState> {
    handleAddOption = (e:any) => {
        e.preventDefault();
        const option = e.target.elements.option.value.trim();
        const err : string = this.props.handleAddOption(option);

        this.setState(() => {
            return {
                error: err
            }
        });

        if (!err) {
            e.target.elements.option.value = '';
        }
    }

    render() {
        console.log(this.state);
        return (
            <div>
                {this.state.error != null ? <p>{this.state.error}</p> : ''}
                <form onSubmit={this.handleAddOption}>
                    <div className="form-group">
                        <label>Enter an Option</label>
                        <input type="text" className="form-control" id="option"  name="option"/>
                    </div>
                    <button className="btn btn-primary">Add option</button>
                </form>
            </div>
        );
    }
};

The statement console.log(this.state); and {this.state.error != null ? <p>{this.state.error}</p> : ''} inside render() is throwing error stating that Uncaught TypeError: Cannot read property 'error' of null. That means this.state is being set as null.

Why is state getting set to null and how do I resolve this ( In TypeScript )?

Thanks in Advance.

8
  • because you didn't define the state, put this inside class: state = {error: ''} or use constructor. Commented Feb 17, 2018 at 8:54
  • Thanks. But I have declared an Interface and passed it as a Generic argument. Isn't it sufficient? Commented Feb 17, 2018 at 8:56
  • What about super() method call? I am not seeing it Commented Feb 17, 2018 at 8:58
  • In super() props will be passed on to the parent component, but I want state only to be maintained in this component. Commented Feb 17, 2018 at 9:00
  • I have one more question, we need to use super(props) only if we define a constructor, if we don't need a constructor in a particular component then no need of super(props)? My doubt is constructor(props) { super(props); } is mandatory or optional. Commented Feb 17, 2018 at 9:02

2 Answers 2

5

As already mentioned in the comments, you have to initialize the state either in the constructor or with a property initializer like this:

class AddOption extends React.Component<IAddOptionProps, IAddOptionState> {

  this.state = {
    error: ''
  };

  [...]

}

Otherwise state will be null and you will get an error like mentioned in your post.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. I initialized state as a property and it’s working now👍
Not sure if it's a version thing, but i believe this needs to be omitted now. If i add it without it being in a constructor, I get an error this.state = become state =
2

You have to initialize your state. There are two ways to do that

The first is to use a property initializer

class AddOption extends React.Component<IAddOptionProps, IAddOptionState> {

  this.state = {
    error: ''
  };

  render() {

    // Now you have your state! Do stuff here

  }

}

The other way is to do it in the constructor

class AddOption extends React.Component<IAddOptionProps, IAddOptionState> {

  constructor(props) {
    super(props);

    this.state = {
      error: ''
    };
  }

  render() {

    // Now you have your state! Do stuff here

  }

}

The solutions are equivalent, though the first is more elegant

2 Comments

The second gives a warning in my case
What warning do you get @DaveHillier?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.