Need to add a simple functionality to a simple calculator made in React JS

Moeez Atlas :

I have made simple calculator in React JS. All the functions are working fine but i need to implement these two functionalities whom i am facing trouble with :

1) When operator(+ or -)is clicked, after that, if again an operator is clicked then the operator should be replaced. For example, if user clicked on +, after that user clicked on – then subtract operation will be performed instead of addition

2)Sequence of operations should be implemented. For example, if user enters 5 and then + and then 4 and then –, it should compute 5+4 and display 9 in the textbox/label

If link does not work here is my code

import React from "react"
import "./style.css"
import "./App.css"


class Layout extends React.Component{
    constructor(){
        super()
        this.state ={
            text: "",
            result: [],
            prevResult: []
        }
        this.handleChange = this.handleChange.bind(this)
        this.calculate = this.calculate.bind(this)
        this.back = this.back.bind(this)
    }

    handleChange(event){ 
        const {name, value, type, checked} = event.target
        this.setState({[name]: value})
    }

    calculate(event){
        this.setState((prevState) => ({
            text: (eval(this.state.text) || "" ) + "",
            result: [...prevState.result, this.state.text + "   " ],
            prevResult: [...prevState.prevResult,  + (eval(this.state.text) || "" ) + "  " ]
            })
        ) 
    }
    back(event){
        const {name, value, type, checked} = event.target
        type === "abc" ? this.setState({text: this.state.text.slice(0, -1)}) : this.setState({text: ""})
    }

    render(){
        return(
           <div > 
            <div className= "resultbar">
               <input style= {{height: "30px", width: "200px", font: "20px" }}
                    name="text"
                    autoFocus="autofocus" 
                    value={this.state.text}
                    onChange = {this.handleChange} 
               />
            </div>

            <div className= "history">
                <h2>History</h2>
                <h3 style= {{color: "red" }}>{this.state.result} </h3>
                <p>{this.state.prevResult}</p>

            </div>

            <div className="button">
                <button 
                    name= "text"
                    value = {this.state.text + "+"}
                    onClick= {this.handleChange}>+</button>

                <button
                    name= "text"
                    value = {this.state.text + "-"}
                    onClick= {this.handleChange}>-</button>

                <button
                    type= "adbc"
                    name= "text"
                    value = {this.state.text + "*"}
                    onClick= {this.handleChange}>*</button>

                <button
                    name= "text"
                    value = {this.state.text + "/"}
                    onClick= {this.handleChange}>/</button>

                <button
                    name= "text"
                    value = {this.state.text + "%"}
                    onClick= {this.handleChange}>%</button>

                <button
                    name= "text"
                    value = {this.state.text + "("}
                    onClick= {this.handleChange}>(</button>

                <button
                    name= "text"
                    value = {this.state.text + ")"}
                    onClick= {this.handleChange}>)</button>

                <button
                    name= "text"
                    type= "dbac"
                    value= {this.state.text}
                    onClick = {this.calculate}>=</button>

                <button 
                    name= "text"
                    value = {this.state.text + "1"}
                    onClick= {this.handleChange}>1</button>

                <button
                    name= "text"
                    value = {this.state.text + "2"}
                    onClick= {this.handleChange}>2</button>

                <button
                    name= "text"
                    value = {this.state.text + "3"}
                    onClick= {this.handleChange}>3</button>

                <button 
                    name= "backspace"
                    onClick = {() => this.setState({
                    text: this.state.text.slice(0, -1)
                    })}> Ce</button>

                <button
                    name= "text"
                    value = {this.state.text + "4"}
                    onClick= {this.handleChange}>4</button>

                <button
                    name= "text"
                    value = {this.state.text + "5"}
                    onClick= {this.handleChange}>5</button>

                <button
                    name= "text"
                    value = {this.state.text + "6"}
                    onClick= {this.handleChange}>6</button>

                <button
                    name= "text"
                    type= "abc"
                    onClick = {this.back} 
                    >C</button>

                <button
                    name= "text"
                    value = {this.state.text + "7"}
                    onClick= {this.handleChange}>7</button>
                <button
                    name= "text"
                    value = {this.state.text + "8"}
                    onClick= {this.handleChange}>8</button>

                <button
                    name= "text"
                    value = {this.state.text + "9"}
                    onClick= {this.handleChange}>9</button>

                <button 
                    name= "backspace"
                    onClick = {() => this.setState({
                    text: this.state.text.slice(0, -1)
                    })}> ~</button>

                <button
                    name= "text"
                    value = {this.state.text + "."}
                    onClick= {this.handleChange}>.</button>

                <button
                    name= "text"
                    value = {this.state.text + "0"}
                    onClick= {this.handleChange}>0</button>
            </div>
        </div>
        )
    }
}
export default Layout
xdeepakv :

You need to check past string value, if last char is operator than update operator. Batter use calculator algorithm stack-based. Just push elements in stack if number, replace if operator, calculate if =.

  1. dont modify the value from the value of button (value={this.state.text + ")"})
  2. Write logic in function

// Clean up of code. https://codesandbox.io/s/eager-haze-gi30v

import React from "react";
import "./style.css";
import "./App.css";
const operators = ["+", "-", "/", "*", "%"];

class Layout extends React.Component {
  constructor() {
    super();
    this.state = {
      text: "",
      result: [],
      prevResult: []
    };
    this.handleChange = this.handleChange.bind(this);
    this.calculate = this.calculate.bind(this);
    this.onChange = this.onChange.bind(this);
  }

  handleChange(event) {
    const { name, value } = event.target;

    let text = this.state.text;
    let lastChar = text.charAt(text.length - 1);
    const isOperator = operators.indexOf(value) !== -1;
    if (value === "=") {
      this.setState(prevState => this.calculate(prevState));
    } else if (value === "CE") {
      this.setState({ text: text.slice(0, -1) });
    } else if (value === "C") {
      this.setState({ text: "" });
    } else if (isOperator && operators.indexOf(lastChar) !== -1) {
      text = text.substr(0, text.length - 1) + value;
      this.setState({ [name]: text });
    } else {
      this.setState({ [name]: text + value });
    }
  }
  onChange({ target }) {
    this.setState({ text: target.value });
  }
  calculate(prevState) {
    try {
      const text = (eval(this.state.text) || "") + "";
      return {
        text,
        result: [...prevState.result, this.state.text + "   "],
        prevResult: [...prevState.prevResult, +text]
      };
    } catch (event) {
      return {
        text: "error",
        result: "error",
        prevResult: "error"
      };
    }
  }
  render() {
    const buttons = [
      "+",
      "-",
      "*",
      "/",
      "%",
      "(",
      ")",
      "=",
      "1",
      "2",
      "3",
      "CE",
      "4",
      "5",
      "6",
      "C",
      "7",
      "8",
      "9",
      "~",
      ".",
      "0"
    ];
    return (
      <div>
        <div className="resultbar">
          <input
            style={{ height: "30px", width: "200px", font: "20px" }}
            name="text"
            autoFocus="autofocus"
            value={this.state.text}
            onChange={this.onChange}
          />
        </div>

        <div className="history">
          <h2>History</h2>
          <h3 style={{ color: "red" }}>{this.state.result} </h3>
          <p>{this.state.prevResult}</p>
        </div>
        <div className="button">
          {buttons.map(x => {
            return (
              <button name="text" value={x} onClick={this.handleChange}>
                {x}
              </button>
            );
          })}
        </div>
      </div>
    );
  }
}
export default Layout;

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=302218&siteId=1