Cannot read state property of null

Tell us what’s happening:

I initialize state as {
formula: ‘’,
result: ‘’
} and at various points in the code these are referenced or inserted as the text of an HTML div and I receive the error “Cannot read property of null”

Also on line 56 I am getting an error on my concat() method even though it does not modify state.

Your code so far

class MyComponent extends React.Component {
 constructor(props) {
   super(props);
   this.setState = { 
     formula: '',
     result: ''
   };
   this.handleNum = this.handleNum.bind(this);
   this.handleEvaluate = this.handleEvaluate.bind(this);
   this.handleClear = this.handleClear.bind(this);
   this.handleClick = this.handleClick.bind(this);
 }
 
 handleClick(event) {
   if (event.target.id == 'equals') {
     this.handleEvaluate(event);
   } else {
     this.handleNum(event);
   }
 }
 handleNum(event) {
   if (this.props.formula == '') {
     this.setState({
       formula: event.target.value
     });
   } else {
       let value = this.props.formula.concat(event.target.value);
       this.setState({
         formula: value
       })
   }
 }
 
 handleEvaluate() {
   let equate = this.state.formula;
   this.setState({
     result: math.evaluate(equate)
   });
 }
 
 handleClear() {
   this.setState = ({
     formula: '',
     result: ''
   });
 }
 
 componentDidMount(){ document.addEventListener("click", this.handleClick)
   }

 render() {
   return (
     <div>
       <div id="display">{this.props.result}</div>
       <button id="zero" onClick={this.handleNum} value="0">0</button>
       <button id="one" onClick={this.handleNum} value="1">1</button>
       <button id="two" onClick={this.handleNum} value="2">2</button>
       <button id="three" onClick={this.handleNum} value="3">3</button>
       <button id="four" onClick={this.handleNum} value="4">4</button>
       <button id="five" onClick={this.handleNum} value="5">5</button>
       <button id="six" onClick={this.handleNum} value="6">6</button>
       <button id="seven" onClick={this.handleNum} value="7">7</button>
       <button id="eight" onClick={this.handleNum} value="8">8</button>
       <button id="nine" onClick={this.handleNum} value="9">9</button>
       <button id="equals" onClick={this.handleEvaluate}>=</button>
       <button id="add" onClick={this.handleNum} value="+">+</button>
       <button id="subtract" onClick={this.handleNum} value="-">-</button>
       <button id="multiply" onClick={this.handleNum} value="*">x</button>
       <button id="divide" onClick={this.handleNum} value="/">/</button>
       <button id="clear" onClick={this.handleClear()}>AC</button>
       <button id="decimal" onClick={this.handleNum} value=".">.</button>
     </div>
   )
 };
}
ReactDOM.render(<MyComponent />, document.getElementById("root"))

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36.

Challenge: Build a JavaScript Calculator

Link to the challenge:

Here’s the link to my code https://codepen.io/modelb/pen/xxEmmjq

Heya, I spotted a couple of typo’s which could be causing problems.

Line 33. Your state initialisation is using setState instead of state which may explain why your initial state object is null.

this.setState = { … }

should be:

this.state = { … }

Line 69. In the handleClear method you’re reassigning the value of setState, essentially overwriting the React components setState method.

this.setState = ({ … })

should be:

this.setState({ … })

Line 81. Displaying a prop instead of state.

{this.props.result}

should be:

{this.state.result}

Line 97. You’re immediately invoking the handleClear event.

onClick={this.handleClear()}

should be:

onClick={this.handleClear}

Thank you so much, I made the corrections you suggested and also noticed that when I clicked a button two numbers would be added because I had the event listener and the onClicks. I’ve removed the onClicks but something is going on because I no longer see the display updating on click. https://codepen.io/modelb/pen/xxEmmjq

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { 
      formula: '',
      result: '0'
    };
    this.handleNum = this.handleNum.bind(this);
    this.handleEvaluate = this.handleEvaluate.bind(this);
    this.handleClear = this.handleClear.bind(this);
    this.handleClick = this.handleClick.bind(this);
  }
  
  handleClick(event) {
    if (event.target.id == 'equals') {
      this.handleEvaluate;
    } else if (event.target.id == 'clear') {
      this.handleClear;
    } else {
      this.handleNum;
    }
  }
  
  handleNum(event) {
    if (!event.target.value === 'undefined') {
      let strNum = this.state.formula + event.target.value;
      this.setState({
        formula: strNum
      })
    }
  }
  
  
  handleEvaluate() {
    let equate = this.state.formula.slice();
    this.setState({
      result: math.evaluate(equate)
    });
  }
  
  handleClear() {
    this.setState({
      formula: '',
      result: '0'
    });
  }
  
  document.addEventListener("click", this.handleClick);

  render() {
    return (
      <div>
        <div id="formulaDisp">{this.state.formula}</div>
        <div id="display">{this.state.result}</div>
        <button id="zero" value="0">0</button>
        <button id="one" value="1">1</button>
        <button id="two" value="2">2</button>
        <button id="three" value="3">3</button>
        <button id="four" value="4">4</button>
        <button id="five" value="5">5</button>
        <button id="six" value="6">6</button>
        <button id="seven" value="7">7</button>
        <button id="eight" value="8">8</button>
        <button id="nine" value="9">9</button>
        <button id="equals">=</button>
        <button id="add" value="+">+</button>
        <button id="subtract" value="-">-</button>
        <button id="multiply" value="*">x</button>
        <button id="divide" value="/">/</button>
        <button id="clear">AC</button>
        <button id="decimal" value=".">.</button>
      </div>
    )
  };
}
ReactDOM.render(<MyComponent />, document.getElementById("root");

I’m no longer seeing the display update at all

You’re missing a closing parenthesis at the end of ReactDOM.render();

There’s some issues in handleClick too but you maybe able to work those out.

Just got it, thank you so much sir!!!