Unable to render the button selected in react

Viewed 61

Can we have two functions inside an onclick event? Here's my code:

import React from 'react';

class Counter extends React.Component {
    state = {
        count: 0,
        inc: 'Increment',
        dec: 'Decrement',
        rst: 'Reset',
    };

    styles = {           //CSS styles into Js objects
        fontSize: 50,
        fontWeight: 'bold',
        margin: 25,
    };

    buttonstyle = {
        padding: 10,
        margin: 15,
        fontSize: 25,
    };

    buttonChange = () => {
        if (this.state.button.id === 1)
          return <p>Increment</p>
        else if (this.state.button.id === 2)
            return <p>Decrement</p>
        else
            return <p>Reset</p>
    }

    addCounter = () => {
        this.state.count++;
        this.setState({ count: this.state.count });
    }

    decrementCounter = () => {
        if (this.state.count > 0) {
            this.state.count--;
            this.setState({ count: this.state.count })
        }
    }

    resetCounter = () => {
        this.state.count = 0;
        this.setState({ count: this.state.count });
    }

    render() {

        let classes = "badge m-2 badge-warning";
        if (this.state.count === 0) {
            classes = "badge badge-warning m-2";
        }
        else {
            classes = "badge badge-success m-2";
        }
        return (

            <div style={{ textAlign: 'center' }}>
                <br></br>
                <span style={this.styles} className={classes}>{this.state.count}</span>
                <br></br>
                <div>
                    <button style={this.buttonstyle} className="btn btn-primary btn-sm" onClick={this.addCounter} id={1}>{this.state.inc}</button>
                    <button style={this.buttonstyle} className="btn btn-primary btn-sm" onClick={this.decrementCounter} id={2}>{this.state.dec}</button>
                    <button style={this.buttonstyle} className="btn btn-primary btn-sm" onClick={this.resetCounter} id={3}>{this.state.rst}</button>
                </div>
                <br></br>
                <div className="container">
                    You have pressed <span style={{ background: 'black', marginRight: 5, color: 'greenyellow' }}>{this.buttonChange} </span> button. //I want to implement the button change here
                </div>
            </div>
        );
    }
}

export default Counter;
1 Answers

The buttonChange is simply returning some JSX computed from state, you can invoke it and render its return value.

<span
  style={{
    background: "black",
    marginRight: 5,
    color: "greenyellow"
  }}
>
  {this.buttonChange()}
</span>

Other issues I see, you are mutating your state object when you post-increment (this.state.count++;) and post-decrement (this.state.count--;). Use a functional state update to increment/decrement from the previous state.

Additionally I added the button ids to your state to match how they were checked in your buttonChange function. Nothing was rendering in the span because you had undefined this.state.button.id state.

addCounter = () => {
  this.setState((prevState) => ({
    count: prevState.count + 1,
    button: { id: 1 }
  }));
};

decrementCounter = () => {
  if (this.state.count > 0) {
    this.setState((prevState) => ({
      count: prevState.count - 1,
      button: { id: 2 }
    }));
  }
};

class Counter extends React.Component {
  state = {
    count: 0,
    inc: "Increment",
    dec: "Decrement",
    rst: "Reset",
    button: { id: null }
  };

  styles = {
    //CSS styles into Js objects
    fontSize: 50,
    fontWeight: "bold",
    margin: 25
  };

  buttonstyle = {
    padding: 10,
    margin: 15,
    fontSize: 25
  };

  buttonChange = () => {
    if (this.state.button.id === 1) return "Increment";
    else if (this.state.button.id === 2) return "Decrement";
    else return "Reset";
  };

  addCounter = () => {
    this.setState((prevState) => ({
      count: prevState.count + 1,
      button: { id: 1 }
    }));
  };

  decrementCounter = () => {
    if (this.state.count > 0) {
      this.setState((prevState) => ({
        count: prevState.count - 1,
        button: { id: 2 }
      }));
    }
  };

  resetCounter = () => {
    this.setState({ count: 0, button: { id: null } });
  };

  render() {
    let classes = "badge m-2 badge-warning";
    if (this.state.count === 0) {
      classes = "badge badge-warning m-2";
    } else {
      classes = "badge badge-success m-2";
    }
    return (
      <div style={{ textAlign: "center" }}>
        <br></br>
        <span style={this.styles} className={classes}>
          {this.state.count}
        </span>
        <br></br>
        <div>
          <button
            style={this.buttonstyle}
            className="btn btn-primary btn-sm"
            onClick={this.addCounter}
            id={1}
          >
            {this.state.inc}
          </button>
          <button
            style={this.buttonstyle}
            className="btn btn-primary btn-sm"
            onClick={this.decrementCounter}
            id={2}
          >
            {this.state.dec}
          </button>
          <button
            style={this.buttonstyle}
            className="btn btn-primary btn-sm"
            onClick={this.resetCounter}
            id={3}
          >
            {this.state.rst}
          </button>
        </div>
        <br></br>
        <div className="container">
          You have pressed{" "}
          <span
            style={{
              background: "black",
              marginRight: 5,
              color: "greenyellow"
            }}
          >
            {this.buttonChange()}
          </span>{" "}
          button.
        </div>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <Counter />,
  rootElement
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Related