Solution 1 :

Please don’t use id with react js, check the code below. in addition, using a hook is a better and fast way to create react components.

import React, { useState } from "react"
import ReactDOM from "react-dom"
import "./style.css"


const JavascriptCalculator = () => {
const [symbol, setSymbol] = useState(0)

const display = (value) => {
   setSymbol(value)
}

const clear = () => {
    setSymbol(0)
}
// dont use id with react, if must try using ref(check reactjs.org for more)
return (
<div id="javascript-calculator">
  <h1 id="title">Javascript Calculator</h1>
  {/*no need for accessing this element id*/}
  <div id="display"><p>{symbol}</p></div>
  <hr/>
  <div>
    <button id="clear" onClick={() => clear()}> clear
    </button>
    {/*pass the value as argument for display function*/}
    <button id="equals" onClick={e => display("=")}> =</button>
    <button id="zero" onClick={e => display("0")}> 0</button>
    <button id="one" onClick={e => display("1")}> 1</button>
    <button id="two" onClick={e => display("2")}> 2</button>
    <button id="three" onClick={e => display("3")}> 3</button>
    <button id="four" onClick={e => display("4")}> 4</button>
    <button id="five" onClick={e => display("5")}> 5</button>
    <button id="six" onClick={e => display("6")}> 6</button>
    <button id="seven" onClick={e => display("7")}> 7</button>
    <button id="eight" onClick={e => display("8")}> 8</button>
    <button id="nine" onClick={e => display("9")}> 9</button>
    <button id="add" onClick={e => display("+")}> +</button>
    <button id="subtract" onClick={e => display("-")}> -</button>
    <button id="multiply" onClick={e => display("*")}> *</button>
    <button id="divide" onClick={e => display("/")}> /</button>
    <button id="decimal" onClick={e => display(".")}> .</button>
  </div>
</div>
)
}

ReactDOM.render(<JavascriptCalculator/>, document.getElementById("app"))

let me know if you have questions

Solution 2 :

The solution:

import React from 'react';
import ReactDOM from 'react-dom';
import './style.css';


class JavascriptCalculator extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      symbol: 0
    }
    this.display = this.display.bind(this);
  }

  display(id){
    this.setState({ symbol: id })
  }

  render() {
    return (
      <div id="javascript-calculator">
      <h1 id="title">Javascript Calculator</h1>
      <div id="display">{this.state.symbol}</div>
      <hr/>
      <div>
      <button id="clear" onClick={e => this.display("0")}> clear</button>
      <button id="equals" onClick={e => this.display("=")}> = </button>
      <button id="zero" onClick={e => this.display("0")}> 0 </button>
      <button id="one" onClick={e => this.display("1")}> 1 </button>
      <button id="two" onClick={e => this.display("2")}> 2 </button>
      <button id="three" onClick={e => this.display("3")}> 3 </button>
      <button id="four" onClick={e => this.display("4")}> 4 </button>
      <button id="five" onClick={e => this.display("5")}> 5 </button>
      <button id="six" onClick={e => this.display("6")}> 6 </button>
      <button id="seven" onClick={e => this.display("7")}> 7 </button>
      <button id="eight" onClick={e => this.display("8")}> 8 </button>
      <button id="nine" onClick={e => this.display("9")}> 9 </button>
      <button id="add" onClick={e => this.display("+")}> + </button>
      <button id="subtract" onClick={e => this.display("-")}> - </button>
      <button id="multiply" onClick={e => this.display("*")}> * </button>
      <button id="divide" onClick={e => this.display("/")}> / </button>
      <button id="decimal" onClick={e => this.display(".")}> . </button>
      </div>
      </div>
    );
  }
}

ReactDOM.render(<JavascriptCalculator />, document.getElementById("app"));

Solution 3 :

Okay… I rewrote your component doing things the React way and using hooks. One of the benefits of JSX is being able to iterate over data and display it without repeating yourself.

Create a file called

symbols.js

export const values = [
    {
        id: 'clear',
        symbol: 'clear'
    },
    {
        id: 'equals',
        symbol: '='
    },
    {
        id: 'zero',
        symbol: '0'
    },
    {
        id: 'one',
        symbol: '1'
    },
    {
        id: 'two',
        symbol: '2'
    },
    {
        id: 'three',
        symbol: '3'
    },
    {
        id: 'four',
        symbol: '4'
    },
    {
        id: 'five',
        symbol: '5'
    },
    {
        id: 'six',
        symbol: '6'
    },
    {
        id: 'seven',
        symbol: '7'
    },
    {
        id: 'eight',
        symbol: '8'
    },
    {
        id: 'nine',
        symbol: '9'
    },
    {
        id: 'subtract',
        symbol: '-'
    },
    {
        id: 'multiply',
        symbol: '*'
    },
    {
        id: 'divide',
        symbol: '/'
    },
    {
        id: 'decimal',
        symbol: '.'
    },
]

In your component import your values and you can iterate over them like so:

import React, { useState } from "react";
import { values } from "./values.js";

const JavascriptCalculator = () => {
  const [symbol, setSymbol] = useState(0);

  const display = (symbol) => {
    setSymbol(symbol);
  };

  const clear = (id) => {
    setSymbol(0);
  };

  return (
    <div id="javascript-calculator">
      <h1 id="title">Javascript Calculator</h1>
      <div id="display">
        <p>{symbol}</p>
      </div>
      <hr />
      <div>
        {values.map(({ id, symbol }) => (
          <button key={id} onClick={() => id === 'clear' ? clear() : display(symbol)}>
            {symbol}
          </button>
        ))}
      </div>
    </div>
  );
};

export default JavascriptCalculator;

Working example https://codesandbox.io/s/magical-brook-enk7e

Solution 4 :

Change this line:

      <button id="clear"  onClick={this.clear('display')}> clear </button>

To this:

      <button id="clear"  onClick={e => this.clear('display')}> clear </button>

You’re not passing the function, but rather executing it directly in the render method. That’s why it cannot find the element with ID “display” – it’s not rendered at all.

Solution 5 :

You could use state for the numbers x and y.

And then have a function to reset by just setting x and y to 0.

Problem :

There is a <div> that contains text which should be cleared when pressing a <button> named “clear”. However, there is an error when it is pressed:
TypeError: null is not an object (evaluating 'document.getElementById(id).innerHTML = "0"')

All the buttons using this.display(e.target.id) work. Only the “clear” button which uses this.clear('display') doesn’t work.

Any help would be greatly appreciated.

index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import './style.css';


class JavascriptCalculator extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
     
    }
    this.display = this.display.bind(this);
    this.clear = this.clear.bind(this);
  }

  display(id){
    let symbol = document.getElementById(id).innerHTML;
    document.getElementById('display').innerHTML = symbol;
  }

  clear(id){
    document.getElementById(id).innerHTML = "0";
  }

  render() {
    return (
      <div id="javascript-calculator">
      <h1 id="title">Javascript Calculator</h1>
      <div id="display"><p>0</p></div>
      <hr/>
      <div>
      <button id="clear"  onClick={this.clear('display')}> clear </button>
      <button id="equals"  onClick={e => this.display(e.target.id)}> = </button>
      <button id="zero"  onClick={e => this.display(e.target.id)}> 0 </button>
      <button id="one"  onClick={e => this.display(e.target.id)}> 1 </button>
      <button id="two"  onClick={e => this.display(e.target.id)}> 2 </button>
      <button id="three"  onClick={e => this.display(e.target.id)}> 3 </button>
      <button id="four"  onClick={e => this.display(e.target.id)}> 4 </button>
      <button id="five"  onClick={e => this.display(e.target.id)}> 5 </button>
      <button id="six"  onClick={e => this.display(e.target.id)}> 6 </button>
      <button id="seven"  onClick={e => this.display(e.target.id)}> 7 </button>
      <button id="eight"  onClick={e => this.display(e.target.id)}> 8 </button>
      <button id="nine"  onClick={e => this.display(e.target.id)}> 9 </button>
      <button id="add"  onClick={e => this.display(e.target.id)}> + </button>
      <button id="subtract"  onClick={e => this.display(e.target.id)}> - </button>
      <button id="multiply"  onClick={e => this.display(e.target.id)}> * </button>
      <button id="divide"  onClick={e => this.display(e.target.id)}> / </button>
      <button id="decimal"  onClick={e => this.display(e.target.id)}> . </button>
      </div>
      </div>
    );
  }
}

ReactDOM.render(<JavascriptCalculator />, document.getElementById("app"));

index.html

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <title>Javascript Calculator</title>
  <style>
  </style>
</head>
<body>
  <main>
    <div id="app"></app>
    </main>
    </script>
  </body>
  </html>

Comments

Comment posted by Paveloosha

Chris G is right. This is not the way you should write code in React. You should use ‘state’ to update text content.

Comment posted by 65535

@Chris G Can

Comment posted by 65535

Can you change your answer so that it only changes the specific code in the question needing changing? In other words, the code in the question has a constructor style and functions that should be preserved where possible, because it is easier to follow.

Comment posted by Mark

Why? Why learn class based components now when hooks are the preferred method?

Comment posted by 65535

@ Besufkad Menji in

Comment posted by 65535

This answer seems complex compared to code in the question which only needed a few edits to correct. However, this answer is a nice re-write of it. Your answer has definitely improved my understanding of React. Thanks!

Comment posted by Mark

I would argue that it simplified the original code quite a bit. It’s much easier to read the component now.

Comment posted by 65535

Your answer is worth more to those who are have advanced knowledge of Javascript and React. For instance, code such as the following is unfamiliar to a beginner:

Comment posted by Mark

How do you figure? That is how you use state in functional components. That is React 101.

Comment posted by Mark

With class based components you have to have knowledge of the contructor, what super is, what the context of this is, binding functions, the component lifecycle, etc. Functional components are much more beginner friendly.

Comment posted by Adam

While true, as other commentors have pointed out, the OP is “doing react wrong” by doing things this way. The answer is correct, but it’s usage to solve the problem should be discouraged.

Comment posted by Mark

This is not the way. Read my answer below for a more react way of handling this.

Comment posted by Kamen Kanev

I agree that it’s not an idiomatically good solution. My answer just fixes the bug and answers the question “Why the code doesn’t work?”.

By