React JS中数组重复值检查替换及星级评分反选实现方案
React评分应用需求实现方案
核心修改点说明
需求1(答题数据去重替换+状态更新)
- 原代码直接修改
this.state.Question数组属于可变操作,React无法触发状态更新,必须通过setState传入新数组实现更新 - 新增数据时先过滤掉相同
QuesID的旧条目,再添加新条目即可实现替换逻辑
需求2(星级反选功能)
toRemove变量赋值时机:检测到当前点击的星级与对应问题已选中的星级完全一致时,设为truetoRemove=true时,直接删除该QuesID对应的所有答题记录,同时将该题所有星星重置为未选中状态
完整修改后代码
import React, { Component } from "react"; import fullStarSrc from "../img/highlightedStar.png"; import emptyStarSrc from "../img/star.png"; export default class testPage extends Component { state = { qtemp2: [ { 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?" }, ], Question: [], }; rate = (event, item) => { const { id } = event.target; let i; const QType = "Rating"; const QuesID = id.substr(1, 2); const OpId = id.charAt(0); const option = id.charAt(0); const Qobj = { QType, QuesID, OpId, option }; // 查找当前问题已有的答题记录 const existRecord = this.state.Question.find(record => record.QuesID === QuesID); // toRemove赋值位置:当前点击的星级和已选星级一致时为true const toRemove = existRecord && existRecord.OpId === OpId; // 生成新的Question数组(先移除同QuesID的旧记录) let newQuestion = this.state.Question.filter(record => record.QuesID !== QuesID); // 不需要删除的情况下才添加新记录 if (!toRemove) { newQuestion.push(Qobj); } // 更新state,回调中处理星级显示 this.setState({ Question: newQuestion }, () => { for (i = 1; i <= 5; i++) { const starId = `${i}${item.idsurveyquestion}`; const starEle = document.getElementById(starId); if (toRemove) { // 反选状态:全部设为空星 starEle.setAttribute("src", emptyStarSrc); } else { // 正常评分:小于等于选中星级的设为满星 starEle.setAttribute("src", i <= parseInt(OpId) ? fullStarSrc : emptyStarSrc); } } }); }; render() { const { qtemp2 } = this.state; return ( <div> <div className="bg"> <div className="bg_img1"></div> <div className="heading1"> <center> <h2 className="head1">Please Rate Us</h2> </center> </div> <center> <div> {qtemp2.map((item) => ( <React.Fragment key={item.idsurveyquestion}> <p>{item.question}</p> <div> <img onClick={(event) => this.rate(event, item)} className="star" id={"1" + item.idsurveyquestion} src={emptyStarSrc} /> <img onClick={(event) => this.rate(event, item)} className="star" id={"2" + item.idsurveyquestion} src={emptyStarSrc} /> <img onClick={(event) => this.rate(event, item)} className="star" id={"3" + item.idsurveyquestion} src={emptyStarSrc} /> <img onClick={(event) => this.rate(event, item)} className="star" id={"4" + item.idsurveyquestion} src={emptyStarSrc} /> <img onClick={(event) => this.rate(event, item)} className="star" id={"5" + item.idsurveyquestion} src={emptyStarSrc} /> </div> </React.Fragment> ))} </div> </center> </div> </div> ); } }
额外优化说明
- 原代码中
class属性在JSX中需要改为className避免语法警告 - 列表渲染时需要给根元素加
key属性,这里替换原来的空片段为React.Fragment绑定key - 所有状态修改都通过
setState实现,确保React触发视图更新
内容的提问来源于stack exchange,提问作者Sidath
相关产品推荐
相关产品推荐

