React中通过传入props设置单选按钮默认选中的最佳实现方式
实现方案说明
你当前代码中直接调用document.getElementById修改DOM属性的写法是React反模式:React采用声明式渲染逻辑,UI应该完全由props/state驱动,手动操作DOM很容易在组件重渲染、props更新时出现状态与UI不一致的问题,也会提升后续维护成本。
最优实现是采用受控组件模式,完全由传入的starClicked prop控制单选框选中状态,不需要任何手动DOM操作:
- 父组件传入
null/0这类不匹配任何星级的初始值时,所有单选框默认未选中 - 传入用户已选择的星级数值时,对应分值的单选框会自动选中
- 点击时通过
handleStarClick向父组件回传选中值,父组件更新状态后回传给组件即可完成选中态切换,全程保证状态与UI一致
改造后代码
function Stars({ handleStarClick, starClicked = null }) { return ( <div className="rate"> <input onClick={() => handleStarClick(5)} type="radio" id="star5" name="rate" value="5" checked={Number(starClicked) === 5} /> <label htmlFor="star5" title="text">5 stars</label> <input onClick={() => handleStarClick(4)} type="radio" id="star4" name="rate" value="4" checked={Number(starClicked) === 4} /> <label htmlFor="star4" title="text">4 stars</label> <input onClick={() => handleStarClick(3)} type="radio" id="star3" name="rate" value="3" checked={Number(starClicked) === 3} /> <label htmlFor="star3" title="text">3 stars</label> <input onClick={() => handleStarClick(2)} type="radio" id="star2" name="rate" value="2" checked={Number(starClicked) === 2} /> <label htmlFor="star2" title="text">2 stars</label> <input onClick={() => handleStarClick(1)} type="radio" id="star1" name="rate" value="1" checked={Number(starClicked) === 1} /> <label htmlFor="star1" title="text">1 star</label> </div> ) }
可选优化:消除重复代码
如果不想重复编写5组结构,可以通过遍历配置数组的方式渲染,代码更简洁易维护:
import { Fragment } from 'react' function Stars({ handleStarClick, starClicked = null }) { // 从5星到1星倒序排列,匹配原有渲染顺序 const starScoreList = [5,4,3,2,1] return ( <div className="rate"> {starScoreList.map(score => ( <Fragment key={score}> <input onClick={() => handleStarClick(score)} type="radio" id={`star${score}`} name="rate" value={String(score)} checked={Number(starClicked) === score} /> <label htmlFor={`star${score}`} title="text"> {score} {score === 1 ? 'star' : 'stars'} </label> </Fragment> ))} </div> ) }
使用注意
- 父组件中存储选中星级的state默认值设为
null即可实现初始全不选效果 - 需要回显用户历史选择时,直接将对应星级数值作为
starClickedprop传入即可,例如传入3时3星选项会自动选中 - 代码中
Number(starClicked)是为了兼容字符串/数字类型的传值,避免类型不匹配导致选中态失效
内容的提问来源于stack exchange,提问作者gliss413
相关产品推荐
相关产品推荐

