InfernoJS/ReactJS - Почему цикл for возвращает тот же индекс в моем рендере?

У меня есть цикл for в моей функции рендеринга, он предназначен для рендеринга 5 звезд из библиотеки fontawesome, рейтинг 3 должен отображать 3 полных звезды и 2 пустых звезды....

у меня проблема в том, что мой итератор "i" возвращается как 5 для всех из них. по крайней мере в моем обработчике onClick. Но что действительно странно, так это то, что если использовать ту же переменную итератора "i", что и id, или любую другую пользовательскую опору для элемента, он отображает правильные значения 1,2,3,4 или 5. Почему это происходит?

import Component from "inferno-component";
import styles from "./styles";
export default class StarRating extends Component {
constructor() {
    super();
    this.state = {
        rating: 3
    };
}

rate = rating => {
    console.log(rating);
    this.setState({
        rating: rating
    });
};
render() {
    var stars = [];
    for (var i = 0; i < 5; i++) {
        var klass = "fa fa-star";

        if (this.state.rating <= i && this.state.rating != null) {
            klass += "-o";
        }

        stars.push(
            <i
                style={styles.star}
                className={klass}
                id={i}
                aria-hidden="true"
                onClick={() => this.rate(i)}
            />
        );
    }
    return <span>{stars}</span>;
}
}

2 ответа

Потянув мои волосы в течение двух часов, я решил проблему, переназначив значение следующим образом.

render() {
    var stars = [];
    for (var i = 0; i < 5; i++) {
        var klass = "fa fa-star";

        if (this.state.rating <= i && this.state.rating != null) {
            klass += "-o";
        }

        let id = i + 1;

        stars.push(
            <i
                style={styles.star}
                className={klass}
                id={i}
                aria-hidden="true"
                onClick={() => this.rate(id)}
            />
        );
    }
    return <span>{stars}</span>;
}

я понятия не имею, как это сработало, но оно сделало свою работу.

Пусть может быть оператором переменной I в области действия уровня блока, используется эквивалент каждого цикла I только текущей области действия уровня блока, только I, поэтому I = 1, 2, 3, 4, 5. и эквивалент Var в глобальная область видимости I, после того, как ссылочный цикл I одинаков, I всегда равен 5. Вы также можете использовать замыкание для кэширования I или использовать let i вместо var i в цикле, как это

for (let i = 0; i < 5; i++) {
    var klass = "fa fa-star";

    if (this.state.rating <= i && this.state.rating != null) {
        klass += "-o";
    }

    stars.push(
        <i
            style={styles.star}
            className={klass}
            id={i}
            aria-hidden="true"
            onClick={() => this.rate(i)}
        />
    );
}


for (var i = 0; i < 5; i++) {
    (function(i){
       var klass = "fa fa-star";


       if (this.state.rating <= i && this.state.rating != null) {
          klass += "-o";
        }

       stars.push(
           <i
            style={styles.star}
            className={klass}
            id={i}
            aria-hidden="true"
            onClick={() => this.rate(i)}
          />
       );
    })(i)
}
Другие вопросы по тегам