squiiiid
squiiiid

Reputation: 93

Passing function to child in React

I'd like to pass functions to the child using props, and create several components that can be clicked on

parent class:

handleClick(i){
    alert(i);
}

render(){
    var items = [];
    for (var i = 0; i < 7; i++) {
      items.push(
        <Item onClick={()=>this.handleClick(i)} />
      );
    }
    return <ul>{items}</ul>;
}

child class:

render() {
    return (
      <li onClick={this.props.onClick}> some names </li>
    );
}

But the result is different from what I expected.

I wanted the first element to alert(0), the second element toalert(1), and so on.

But instead, all elements shows 7 when I click on them. I guess that's because I'm always using the i after for-loop has finished.

I guess this is a problem about basic concepts of scopes or using closure or something, rather than a React problem. But still I can't find a right way to fix this problem.

Upvotes: 1

Views: 54

Answers (1)

Shubham Khatri
Shubham Khatri

Reputation: 281864

It happens because of closure, since your are using var keyword for forLoop iterator, its scope will be the render function and the value passed to handleClick will always be the updated value of iterator. Use let keyword to solve closure issue

render(){
    var items = [];
    for (let i = 0; i < 7; i++) {  // let keyword for iterator
      items.push(
        <Item onClick={()=>this.handleClick(i)} />
      );
    }
    return <ul>{items}</ul>;
}

Even with var, you can solve the closure issue using anonymous function

render(){
    var items = [];
    for (var i = 0; i < 7; i++) {
      (function(index){
          items.push(
              <Item onClick={()=>this.handleClick(i)} />
          );
      }.bind(this))(i)
    }
    return <ul>{items}</ul>;
}

Upvotes: 2

Related Questions