首页 > 解决方案 > this.handleSetRating(i + 1) 如何在 StarRating 组件中工作?

问题描述

这是 StarRating 组件 =>

class StarRating extends Component {
  state = {
    rating: 0,
  };
  renderStars = () => {
    let stars = [];
    let maxRating = 5;

    for (let i = 0; i < maxRating; i++) {
      stars.push(
        <Star
          isSelected={this.state.rating > i}
          setRating={() => this.handleSetRating(i + 1)}
          key={i}
        />
      );
    }
    return stars;
  };
  handleSetRating = (rating) => {
    if (this.state.rating === rating) {
      this.setState({ rating: 0 });
    } else {
      this.setState({ rating });
    }
  };

  render() {
    return <ul className="course--stars">{this.renderStars()}</ul>;
  }
}

这是 Star 组件 =>

const Star = (props) => (
  <li 
    className={props.isSelected ? "selected" : null} 
    onClick={props.setRating}>
    <svg x="0px" y="0px" viewBox="0 0 16 15" className="star">
      <path
        d="M8.5,0.3l2,4.1c0.1,0.2,0.2,0.3,0.4,0.3l4.6,0.7c0.4,0.1,0.6,0.6,0.3,0.9l-3.3,3.2c-0.1,0.1-0.2,0.3-0.2,0.5l0.8,4.5
      c0.1,0.4-0.4,0.8-0.8,0.6l-4.1-2.1c-0.2-0.1-0.3-0.1-0.5,0l-4.1,2.1c-0.4,0.2-0.9-0.1-0.8-0.6l0.8-4.5c0-0.2,0-0.4-0.2-0.5L0.2,6.2
      C-0.2,5.9,0,5.4,0.5,5.3L5,4.7c0.2,0,0.3-0.1,0.4-0.3l2-4.1C7.7-0.1,8.3-0.1,8.5,0.3z"
      />
    </svg>
  </li>
);

当 onClick 函数在 Star 组件上调用 this.handleSetRating() 函数时,循环内的 this.handleSetRating() 函数如何工作?


准确地说,当 for 循环运行时,我会感到困惑,setRating()Star 组件是否会立即得到解决并调用 this.handleSetRating(i + 1);当发生时将导致无限循环,或者它使用闭包来记住每次迭代后的第 i 个值,因此当它被onClickon Star 组件调用时,它使用闭包来使用 I 值。

标签: javascriptclosures

解决方案


...或者它在每次迭代后使用闭包来记住第 i 个值,因此当它被onClickon Star 组件调用时,它使用闭包来使用i

这就是它正在做的事情。它之所以有效,i是因为在for循环初始化部分使用let. 如果i在循环外声明,或者用var.

这是一个更简单的例子:

for (let i = 0; i < 5; ++i) {
    setTimeout(() => console.log(i), i * 200);
}

传入setTimeout的函数就像你的onClick. for该函数的代码在循环期间不被调用,而是在稍后调用。但它引用了i创建时存在的副本。当您letfor循环初始化器中使用时,会为每个循环迭代创建一个不同的。 i


推荐阅读