Mohamed Ali
Mohamed Ali

Reputation: 782

Not able to see value of increment button

New to react and I am removing the local state in my counter component and will be relying on the props to receive the data that it needs. I believe this is called a controlled component. After I got rid of the state and changed every where I was using this.state to this.props, I am no longer able to see the box that displays the value when I click my increment button. I will post all the code down below.

/* Counter Component*/

import React, { Component } from "react";

class Counter extends Component {
renderTags() {
return (
  <ul>
    {this.state.tags.length === 0 && <p> There are no tags </p>}
    {this.state.tags.map(tag => (
      <li key={tag}> {tag} </li>
    ))}
  </ul>
    );
  }

  // You can do styles this way or do it inline
  //   styles = {
  //     fontSize: 50,
  //     fontWeight: "bold"
  //   };


 render() {
 return (
  <div>
    <span style={{ fontSize: 20 }} className={this.getBadgeClasses()}>
      {this.formatCount()}
    </span>
    <button
      onClick={() => this.props.onIncrement(this.props.counter)}
      className="btn btn-secondary btn-sm"
    >
      Increment
    </button>

    <button
      onClick={() => this.props.onDelete(this.props.counter.id)}
      className="btn btn-danger btn-sm m-2"
    >
      Delete
    </button>

    {/* {this.renderTags()}
    <p>{this.state.tags.length === 0 && "Please create a new tag"}</p> */}
  </div>
);
 }

  getBadgeClasses() {
    let classes = "badge m-2 badge-";
    classes += this.props.counter.value === 0 ? "warning" : "primary";
    return classes;
  }

 formatCount() {
const { count } = this.props.counter;
return count === 0 ? "Zero" : count;
  }
}

export default Counter;

/* Counters Component */

import React, { Component } from "react";
import Counter from "./counter";

class Counters extends Component {
 state = {
counters: [
  { id: 1, value: 5 },
  { id: 2, value: 0 },
  { id: 3, value: 0 },
  { id: 4, value: 0 }
]
 };

 handleIncrement = counter => {
console.log(counter);
};

  handleReset = () => {
   const counters = this.state.counters.map(c => {
  c.value = 0;
  return c;
});
this.setState({ counters });
  };

 handleDelete = counterID => {
const counters = this.state.counters.filter(c => c.id !== 
   counterID);
   this.setState({ counters });
 };

 render() {
   return (
  <React.Fragment>
    <button onClick={this.handleReset} className="btn btn-dark btn-sm m-2">
      Reset
    </button>
    {this.state.counters.map(counter => (
      <Counter
        key={counter.id}
        onDelete={this.handleDelete}
        counter={counter}
        onIncrement={this.handleIncrement}
      />
    ))}
  </React.Fragment>
   );
    }
  } 

  export default Counters;

Upvotes: 0

Views: 58

Answers (1)

devserkan
devserkan

Reputation: 17608

You can't see the values since you are using a wrong key for your counter.

formatCount() {
    const { count } = this.props.counter;
    return count === 0 ? "Zero" : count;
}

There isn't any key named count in your counter. It is value. So, you should use it or you need to destruct it like this:

const { value: count } = this.props.counter

But, using the same name is more consistent I think. Also, your Counter component would be a stateless one since you don't need any state or lifecycle method there.

One extra change would be done to the handler methods like onClick for onIncrement. If you use an arrow function, that function will be recreated in every render. You can use an extra handler method. Here is the complete working example (simplified for a clear view).

class Counters extends React.Component {
  state = {
    counters: [
      { id: 1, value: 5 },
      { id: 2, value: 0 },
      { id: 3, value: 0 },
      { id: 4, value: 0 }
    ]
  };

  handleIncrement = counter => {
    const { counters } = this.state;
    const newCounters = counters.map( el => {
      if( el.id !== counter.id ) { return el; }
      return { ...counter, value: counter.value + 1 }
    } )
    this.setState({ counters: newCounters});
  };

  handleReset = () => {
    const counters = this.state.counters.map(c => {
      c.value = 0;
      return c;
    });
    this.setState({ counters });
  };

  handleDelete = counter => {
    const { id: counterID } = counter;
    const counters = this.state.counters.filter(c => c.id !== counterID);
    this.setState({ counters });
  };

  render() {
    return (
      <div>
        <button onClick={this.handleReset} className="btn btn-dark btn-sm m-2">
          Reset
        </button>
        {this.state.counters.map(counter => (
          <Counter
            key={counter.id}
            onDelete={this.handleDelete}
            counter={counter}
            onIncrement={this.handleIncrement}
          />
        ))}
      </div>
    );
  }
}

const Counter = props => {
  const { counter, onIncrement, onDelete} = props;

  function formatCount(){
    const { value } = counter;
    return value === 0 ? "Zero" : value;
  }

  function handleIncrement(){
    onIncrement( counter );
  }

  function handleDelete(){
    onDelete( counter );
  }

  return (
    <div>
      <span>
        {formatCount()}
      </span>
      <button
        onClick={handleIncrement}
      >
        Increment
        </button>

      <button
        onClick={handleDelete}
      >
        Delete
        </button>
    </div>
  );
}

ReactDOM.render(<Counters />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Upvotes: 1

Related Questions