React星级评分组件点击<i>元素获取e.target.value为undefined如何解决
问题原因
<i> 属于普通HTML标签,没有内置的value属性,只有input、select这类表单元素的value属性可以通过DOM对象的.value直接读取。你写在<i>上的value是自定义属性,属于元素的attribute,不能通过e.target.value直接访问。
解决方案
这里提供三种可行的修改方式,按需选择即可:
方式1:用getAttribute读取自定义属性
直接修改取值逻辑,调用DOM元素的getAttribute方法获取你定义的value属性,注意要转成数字类型,避免后续判断出错:
const [rating, setRating] = useState(1) const setRatingHandler = (e) => { const starValue = Number(e.target.getAttribute('value')) // 加判断避免点击到父级div时拿到null报错 if(starValue) setRating(starValue) } // 这里可以简化onClick的写法,不需要多包一层箭头函数 <div onClick={setRatingHandler} className="review-stars flex justify-self-start rating mb-6 ml-1"> <i className={rating >= 1 ? 'fas fa-star' : rating >= 0.5 ? 'fas fa-star-half-alt' : 'far fa-star'} value="1"></i> <i className={rating >= 2 ? 'fas fa-star' : rating >= 1.5 ? 'fas fa-star-half-alt' : 'far fa-star'} value="2"></i> <i className={rating >= 3 ? 'fas fa-star' : rating >= 2.5 ? 'fas fa-star-half-alt' : 'far fa-star'} value="3"></i> <i className={rating >= 4 ? 'fas fa-star' : rating >= 3.5 ? 'fas fa-star-half-alt' : 'far fa-star'} value="4"></i> <i className={rating >= 5 ? 'fas fa-star' : rating >= 4.5 ? 'fas fa-star-half-alt' : 'far fa-star'} value="5"></i> </div>
方式2:用标准data-*自定义属性(更规范)
把<i>上的value属性换成符合HTML规范的data-*格式,通过dataset属性读取,语义性更好:
首先修改每个<i>的属性:
<i data-value="1" ...></i> <i data-value="2" ...></i> <!-- 剩下的星星同理修改 -->
然后修改取值逻辑:
const starValue = Number(e.target.dataset.value)
方式3:直接绑定点击事件传值(最推荐)
不用事件委托,直接给每个星星绑定点击事件并传入对应分值,不需要处理事件对象,逻辑更直观,也不会出现target匹配错误的问题,还可以用循环简化重复代码:
const [rating, setRating] = useState(1) const starList = [1,2,3,4,5].map(val => ( <i key={val} className={rating >= val ? 'fas fa-star' : rating >= val - 0.5 ? 'fas fa-star-half-alt' : 'far fa-star'} onClick={() => setRating(val)} /> )) return <div className="review-stars flex justify-self-start rating mb-6 ml-1"> {starList} </div>
内容的提问来源于stack exchange,提问作者pancake
相关产品推荐
相关产品推荐

