如何在 React JS 中评分星级?

How to make rating stars in react js?

我正在使用 React js 创建一个调查应用程序,并使用 fetch 方法从 API 获取所有数据。我已经制作了评级调查页面,并想让这些明星发挥作用。我已经尝试用 png 图像对星星进行评级,并且它可以很好地解决 1 个问题。但是当我添加另一个带有该评级星的问题时,它不起作用。

这是我试过的

这是我的代码

import React, { Component } from "react";
import fullStarSrc from "../img/highlightedStar.png";
import emptyStarSrc from "../img/star.png";

export default class testPage extends Component {
  state = {
    qtemp3: [
      { idsurveyquestion: "22", question: "Taste of the food?" },
      { idsurveyquestion: "23", question: "Quality of the food?" },
      { idsurveyquestion: "24", question: "Speed Of delivery?" },
      { idsurveyquestion: "25", question: "The accuracy of the order?" },
      { idsurveyquestion: "26", question: "How is our service?" },
    ],
  };


  rate = (event) => {
    const { id } = event.target;
    var i;

    for (i = 1; i <= 5; i++) {
      if (i <= parseInt(id)) {
        document.getElementById(i).setAttribute("src", fullStarSrc);
      } else {
        document.getElementById(i).setAttribute("src", emptyStarSrc);
      }
    }
  };

  render() {
    const { qtemp3 } = this.state;
    return (
      <div>
        <div class="bg">
          <div class="bg_img1"></div>
          <div class="heading1">
            <center>
              <h2 class="head1">Please Rate Us</h2>
            </center>
          </div>
          <center>
            <div>
              {qtemp3.map((item) => (
                <>
                  <p key={item.idsurveyquestion}>{item.question}</p>
                  <div>
                    <img onClick={this.rate} class="star" id="1" src={emptyStarSrc} />
                    <img onClick={this.rate} class="star" id="2" src={emptyStarSrc} />
                    <img onClick={this.rate} class="star" id="3" src={emptyStarSrc} />
                    <img onClick={this.rate} class="star" id="4" src={emptyStarSrc} />
                    <img onClick={this.rate} class="star" id="5" src={emptyStarSrc} />
                  </div>
                </>
              ))}
            </div>
          </center>
        </div>
      </div>
    );
  }
}

现在我需要让所有的星星都工作起来作为第一个问题。我该如何解决这个问题?请帮助我。

最快的解决方案是为 img 创建一个索引,该索引是渐进索引和 itemidsurveyquestion 的组合。所以:

import React, { Component } from "react";
import fullStarSrc from "../img/highlightedStar.png";
import emptyStarSrc from "../img/star.png";

export default class testPage extends Component {
  state = {
    qtemp3: [
      { idsurveyquestion: "22", question: "Taste of the food?" },
      { idsurveyquestion: "23", question: "Quality of the food?" },
      { idsurveyquestion: "24", question: "Speed Of delivery?" },
      { idsurveyquestion: "25", question: "The accuracy of the order?" },
      { idsurveyquestion: "26", question: "How is our service?" },
    ],
  };


  rate = (event, item) => {
    const { id } = event.target;
    var i;

    for (i = 1; i <= 5; i++) {
      if (parseInt(i + item.idsurveyquestion) <= parseInt(id)) {
        document.getElementById(parseInt(i + item.idsurveyquestion)).setAttribute("src", fullStarSrc);
      } else {
        document.getElementById(parseInt(i + item.idsurveyquestion)).setAttribute("src", emptyStarSrc);
      }
    }
  };

  render() {
    const { qtemp3 } = this.state;
    return (
      <div>
        <div class="bg">
          <div class="bg_img1"></div>
          <div class="heading1">
            <center>
              <h2 class="head1">Please Rate Us</h2>
            </center>
          </div>
          <center>
            <div>
              {qtemp3.map((item) => (
                <>
                  <p key={item.idsurveyquestion}>{item.question}</p>
                  <div>
                    <img onClick={(event) => this.rate(event, item)} class="star" id={"1" + item.idsurveyquestion} src={emptyStarSrc} />
                    <img onClick={(event) => this.rate(event, item)} class="star" id={"2" + item.idsurveyquestion} src={emptyStarSrc} />
                    <img onClick={(event) => this.rate(event, item)} class="star" id={"3" + item.idsurveyquestion} src={emptyStarSrc} />
                    <img onClick={(event) => this.rate(event, item)} class="star" id={"4" + item.idsurveyquestion} src={emptyStarSrc} />
                    <img onClick={(event) => this.rate(event, item)} class="star" id={"5" + item.idsurveyquestion} src={emptyStarSrc} />
                  </div>
                </>
              ))}
            </div>
          </center>
        </div>
      </div>
    );
  }
}

有一些注意事项:正如@jonrsharpe 在评论中所说,不鼓励在 React 中进行 DOM 操作,您应该使用状态变量使 DOM 动态化。

所以在这种情况下,您应该创建一个状态变量,它是布尔数组的集合:

  state = {
    qtemp3: [
      { id:0, idsurveyquestion: "22", question: "Taste of the food?" },
      { id:1, idsurveyquestion: "23", question: "Quality of the food?" },
      { id:2, idsurveyquestion: "24", question: "Speed Of delivery?" },
      { id:3, idsurveyquestion: "25", question: "The accuracy of the order?" },
      { id:4, idsurveyquestion: "26", question: "How is our service?" },
    ],
    rating: [[false, false, false, false, false],
             [false, false, false, false, false],
             [false, false, false, false, false],
             [false, false, false, false, false],
             [false, false, false, false, false]]
  };

然后使用 rate funciotn 将相应数组的所有元素设置为 true,最后使用 rating state:

条件 html
  rate = (event, item) => {
    const { id } = event.target;
    var i;
    let ratingCopy = [...this.state.rating]

    for (i = 1; i <= 5; i++) {
      if (i <= parseInt(id)) {
        ratingCopy[item.id][i - 1] = true
      } else {
        ratingCopy[item.id][i - 1] = false
      }
    }

    this.setState({ rating: ratingCopy })
  };

render() {
    const { qtemp3 } = this.state;
    return (
      <div>
        <div class="bg">
          <div class="bg_img1"></div>
          <div class="heading1">
            <center>
              <h2 class="head1">Please Rate Us</h2>
            </center>
          </div>
          <center>
            <div>
              {qtemp3.map((item) => (
                <>
                  <p key={item.idsurveyquestion}>{item.question}</p>
                  <div>
                    <img onClick={(event) => this.rate(event, item)} class="star" id="1" src={this.state.rating[item.id][0] ? fullStarSrc : emptyStarSrc} />
                    <img onClick={(event) => this.rate(event, item)} class="star" id="2" src={this.state.rating[item.id][1] ? fullStarSrc : emptyStarSrc} />
                    <img onClick={(event) => this.rate(event, item)} class="star" id="3" src={this.state.rating[item.id][2] ? fullStarSrc : emptyStarSrc}/>
                    <img onClick={(event) => this.rate(event, item)} class="star" id="4" src={this.state.rating[item.id][3] ? fullStarSrc : emptyStarSrc} />
                    <img onClick={(event) => this.rate(event, item)} class="star" id="5" src={this.state.rating[item.id][4] ? fullStarSrc : emptyStarSrc} />
                  </div>
                </>
              ))}
            </div>
          </center>
        </div>
      </div>
    );
  }