this.handleSetRating(i + 1) 如何在 StarRating 组件中工作?
How this.handleSetRating(i + 1) is working in StarRating component?
这是 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>;
}
}
这是星组件=>
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() 函数如何工作?
准确地说,当 for 循环运行时我感到困惑,Star 组件上的 setRating()
是否立即得到 解析并调用 this.handleSetRating(i + 1);这在发生时会导致无限循环,或者它使用 closure 来记住每次迭代后的第 i 个值,因此当它被 Star 组件上的 onClick
调用时,它使用闭包 使用 I 值。
...or it is using closure to remember the ith value after each iteration so when it was called by the onClick
on Star component it uses a closure to use i
value
这就是它正在做的事情。它之所以有效,是因为 i
是在 for
循环初始化部分使用 let
声明的。如果 i
在循环外声明,或者用 var
.
声明,它将无法正常工作
这是一个更简单的例子:
for (let i = 0; i < 5; ++i) {
setTimeout(() => console.log(i), i * 200);
}
传递给 setTimeout
的函数就像在您的 onClick
中使用的函数一样。在 for
循环期间不调用该函数的代码,它在 之后 被调用。但是它引用了创建时存在的 i
的副本。当您在 for
循环初始值设定项中使用 let
时,会为每个循环迭代创建一个 不同的 i
。
这是 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>;
}
}
这是星组件=>
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() 函数如何工作?
准确地说,当 for 循环运行时我感到困惑,Star 组件上的 setRating()
是否立即得到 解析并调用 this.handleSetRating(i + 1);这在发生时会导致无限循环,或者它使用 closure 来记住每次迭代后的第 i 个值,因此当它被 Star 组件上的 onClick
调用时,它使用闭包 使用 I 值。
...or it is using closure to remember the ith value after each iteration so when it was called by the
onClick
on Star component it uses a closure to usei
value
这就是它正在做的事情。它之所以有效,是因为 i
是在 for
循环初始化部分使用 let
声明的。如果 i
在循环外声明,或者用 var
.
这是一个更简单的例子:
for (let i = 0; i < 5; ++i) {
setTimeout(() => console.log(i), i * 200);
}
传递给 setTimeout
的函数就像在您的 onClick
中使用的函数一样。在 for
循环期间不调用该函数的代码,它在 之后 被调用。但是它引用了创建时存在的 i
的副本。当您在 for
循环初始值设定项中使用 let
时,会为每个循环迭代创建一个 不同的 i
。