Search code examples
javascriptreactjscomponents

React updating elements from one file to other


Hello Guys I am a newbie and trying to learn React. I want to access the state of counters.js from counter.js in the delete button. I tried to print but the output is giving as undefined. The expected output is the button id clicked. Please somebody help. and can someone suggest me a good course to learn React and front-end development?

counter.js


class Counter extends Component {
  state = {
    value: this.props.value
  }
  handleIncrement = () => {
    this.setState({
      value: this.state.value + 1
    })
  }

  render() {

    return (<div>
      {this.props.children}
      <span className={this.getBadgeClasses()}>{this.formatCount()}</span>
      <button onClick={this.handleIncrement} className='btn btn-secondary btn-sm'>Increment</button>
      <button onClick={() => this.props.onDelete(this.props.id)} className="btn btn-danger btn-sm m-2">Delete</button>
    </div>);
  }
  formatCount() {
    const {value} = this.state;
    return value === 0
      ? "Zero"
      : value;
  }

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

export default Counter;

Counters.js

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

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

  handleDelete = (counterId) => {
    console.log('Event Handler Called', counterId);
  }
  render() {

    return (<div>
      {this.state.counters.map(counter => (<Counter key={counter.id} onDelete={this.handleDelete} value={counter.value}/>))}

    </div>)
  }
}

export default Counters;

console the console output is returning undefined but expected is the button clicked (1,2),


Solution

  • change word key to any other letter) and it should works fine

    {this.state.counters.map(counter => (<Counter key={counter.id}
    to 
    {this.state.counters.map(counter => (<Counter a={counter.id} 
    and this line also
    <button onClick={() => this.props.onDelete(this.props.key)}
    to 
    <button onClick={() => this.props.onDelete(this.props.a)}

    also you can add a key in this way

    (counter, i) => (<Counter key={i} a={counter.id}
    

    here is your working solution in two files

    Counters.js

    export default class Counters extends Component {
        constructor(props) {
            super(props)
    
            this.state = {
                counters: [
                  {
                    id: 1,
                    value: 4
                  }, {
                    id: 2,
                    value: 0
                  }, {
                    id: 3,
                    value: 0
                  }, {
                    id: 4,
                    value: 0
                  }
                ]
              };
    
              this.handleDelete = this.handleDelete.bind(this)
        }
      
      handleDelete = (counterId) => {
        console.log(counterId)
        console.log('Event Handler Called', counterId);
      }
      render() {
        return (<div>
          {this.state.counters.map(counter => (<Counter a={counter.id} onDelete={this.handleDelete} value={counter.value}/>))}
    
        </div>)
      }
    }

    counter.js

    import React from 'react'
    
    
    class Counter extends React.Component {
        constructor(props) {
            super(props)
    
            this.state = {
                value: this.props.value
            }
    
            this.getBadgeClasses = this.getBadgeClasses.bind(this)
            this.formatCount = this.formatCount.bind(this)
        }
        handleIncrement = () => {
            
          this.setState({
            value: this.state.value + 1
          })
        }
      
        render() {
          return (<div>
            {this.props.children}
            <span className={this.getBadgeClasses()}>{this.formatCount()}</span>
            <button onClick={this.handleIncrement} className='btn btn-secondary btn-sm'>Increment</button>
            <button onClick={() => this.props.onDelete(this.props.a)} className="btn btn-danger btn-sm m-2">Delete</button>
          </div>);
        }
        formatCount() {
          const {value} = this.state;
          return value === 0
            ? "Zero"
            : value;
        }
      
        getBadgeClasses() {
          let classes = "badge m-2 badge-";
          classes += this.state.value === 0
            ? "warning"
            : "primary";
          return classes;
        }
      }
      
      export default Counter;