0

in counters component counters have 4 arrays of items I want to display their value on header(h1) when we click on increment button it gives 4, <h1>{this.state.counters.filter(c=>c.value>0).length}</h1> enter image description here

I want to add all increment in h1 here is my code of parent component

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

    }
    handleIncrement=counter=>{
        const counters =[...this.state.counters];
        const index = counters.indexOf(counter);
        counters[index]={...counter}
        counters[index].value++;
        this.setState({counters})
    }
    handleDelete=(counterid)=>{
      const counters = this.state.counters.filter(m=>m.id !== counterid)
      this.setState({counters})
    }
    handleReset=()=>{
        const counters = this.state.counters.map(m=>{ 
            m.value = 0;
             return m
        })
        this.setState({counters})

    }
    
    render() {
        
        return (
            <div>
                <h1>{this.state.counters.filter(c=>c.value>0).length}</h1>
                <button onClick={this.handleReset} className="btn btn-secondary btn-sm">RESET</button>
           {this.state.counters.map(m=>
           <Counter key={m.id} 
             id={m.id} getDelete={this.handleDelete}
              onIncrement={this.handleIncrement}
              counter={m}
              >
           
              
           </Counter>) }


            </div>

        );
    }
}
kukab
  • 561
  • 5
  • 18

1 Answers1

1

What you are doing wrong here is getting the filter.length. this will only return the number or counter object that has a value greater than one, which will max to 4: the number of counter objects that you have.

to get the sum of the values inside each of the counter object, you should reduce the counter array by summing the values as follows

<h1>{this.state.counters.reduce((a, b) => ({value: a.value + b.value})).value}</h1>

More about reducing an array of objects can be found on this stack answer

akram-adel
  • 920
  • 7
  • 8
  • why weare using .value after reduce – kukab Aug 26 '20 at 13:28
  • If you check this [stack question](https://stackoverflow.com/questions/5732043/javascript-reduce-on-array-of-objects) you will find it is similar to your case because you don't have an array of numbers, you have an array of objects.the answer in the stack question I linked have detailed explanation – akram-adel Aug 26 '20 at 16:54
  • 1
    Having a reduce function this way `(a, b) => ({value: a.value + b.value}))` don't return a number, it returns an object `{value: xxx}` where `xxx` is a number. That is why in the end of the reduce return I had to use `.value` to get the actual number – akram-adel Aug 26 '20 at 16:56