ep84
ep84

Reputation: 365

Why is my onClick event not triggering on React?

I can't spot why my onClick event is not working in my React app.

I'm trying to create a line of divs with the letters of the alphabet. When one of the divs is clicked, the div with its letter should be removed from the line.

I've attached the onClick event to the divs as part of a mapping of an alphabet string in my state, but I seem to be missing/overlooking something, because I can't click on the divs at all.

I've made sure to bind the function in constructor.

let { Grid, Row, Col } = ReactBootstrap;

class Letter extends React.Component {
  
  render () {
    const style = { border: '1px solid black',
                    display: 'inline-block',
                    fontSize: '4vw',
                    width: '4vw',
                    height: '8vh',
                    textAlign: 'center'};
    
    return (<div style={style} key={this.props.key}>
              {this.props.letter}
            </div>);
    
  }
}

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    
    this.state = {
      alpha: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    };
    
    this.callLetter = this.callLetter.bind(this);
  }
 
  callLetter(e) {
    var letterindex = this.state.alpha.indexOf(e.currentTarget.attributes[0].value);
    var alphaclone = this.state.alpha;
    
    alphaclone = alphaclone.slice(0, letterindex) + alphaclone.slice(letterindex + 1);
    
    this.setState({alpha:alphaclone});
  }
  
  render() {

    return (   
      <Grid>
        <Row className="show-grid" >
          {this.state.alpha.split('').map((item, i) =>
            (
                <Letter letter = {item} key = {i} onClick = {this.callLetter}/> 
            ))}
        </Row>
      </Grid>
    );
  }  
}

ReactDOM.render(
  <MyComponent/>,
  document.getElementsByClassName('container-fluid')[0]
);

Thank you.

Upvotes: 1

Views: 97

Answers (1)

Kenneth Truong
Kenneth Truong

Reputation: 4166

You need to add onClick into your Letter component.

(Your Letter component gets an onClick prop but it doesn't use it.)

class Letter extends React.Component {

  render () {
    const style = { border: '1px solid black',
                display: 'inline-block',
                fontSize: '4vw',
                width: '4vw',
                height: '8vh',
                textAlign: 'center'};

    return (
      <div 
        style={style} 
        key={this.props.key} 
        onClick={this.props.onClick} // Have to pass onClick to div
      >
        {this.props.letter}
      </div>
    );
  }
}

What happens is onClick is a property that only DOM elements know about. While Letter is a React Component you created so you need to specify what to do with the onClick

 <Letter letter={item} key={i} onClick={this.callLetter}/> 

Note: The code above only fixes the issue to make sure that the onClick is handled. What you want to do now is make sure that your callLetter is getting the correct letter by making your Letter component handle the event.

class Letter extends React.Component {
  onHandleClick = () => {
    this.props.onClick(this.props.letter);
  };

  render () {
    const style = { border: '1px solid black',
                display: 'inline-block',
                fontSize: '4vw',
                width: '4vw',
                height: '8vh',
                textAlign: 'center'};

    return (
      <div 
        style={style} 
        key={this.props.key} 
        onClick={this.onHandleClick} // Have to pass onClick to div
      >
        {this.props.letter}
      </div>
    );
  }
}

For your callLetter change the parameter to expect a letter.

callLetter(letter) {
    var letterindex = this.state.alpha.indexOf(letter);
    var alphaclone = this.state.alpha;

    alphaclone = alphaclone.slice(0, letterindex) + alphaclone.slice(letterindex + 1);

    this.setState({alpha:alphaclone});
  }

Upvotes: 1

Related Questions