如何在React中创建带图标下拉菜单?react-select显示异常问题求助
react-select 带图标下拉异常修复方案
核心问题
react-select的value属性要求传入和options结构一致的完整对象,你当前只传入了this.props.user.presence.value字符串,无法匹配到对应选项,导致选中值和图标渲染异常。- 若使用v2及以上版本的
react-select,optionRenderer、valueRenderer已废弃,需改用components属性传递自定义渲染组件。 - 自定义渲染函数未绑定
this,会导致上下文指向异常。
修正代码
import React from "react"; import { connect } from "react-redux"; import FontAwesome from "react-fontawesome"; import Select from "react-select"; import { setPresence } from "../../ducks/user"; import "./UserInfo.css"; class UserInfo extends React.Component { presenceOpts = [ { value: "available", label: "Available" }, { value: "dnd", label: "Busy" }, { value: "away", label: "Away" }, ]; // 改为箭头函数绑定this setPresenceFun = (presence) => { // 如果redux只需要存value值,这里可以传presence.value this.props.setPresence(presence); } // 改为箭头函数绑定this renderPresenceOption = (option) => { return ( <div className="presenceOption"> <FontAwesome name="circle" className={"presenceIcon " + option.value} /> {option.label} </div> ); } // 改为箭头函数绑定this renderPresenceValue = (presence) => { return ( <div className="currentPresence"> <FontAwesome name="circle" className={"presenceIcon " + presence.value} /> {/* 如果需要同时显示状态文字可以加下面这行 */} {/* {presence.label} */} </div> ); } render() { // 匹配完整的选项对象作为value const selectedPresence = this.presenceOpts.find(opt => opt.value === this.props.user.presence.value) || this.presenceOpts[0]; return ( <div className="UserInfo"> {this.props.client.authenticated && ( <div className="authenticated"> <div className="user"> <div className="presenceControl"> <Select name="presence" value={selectedPresence} options={this.presenceOpts} onChange={this.setPresenceFun} clearable={false} {/* 兼容v1版本保留下面两个属性,v2+版本删除下面两个属性改用components配置 */} optionRenderer={this.renderPresenceOption} valueRenderer={this.renderPresenceValue} {/* v2+版本请打开下面的components配置 */} {/* components={{ Option: this.renderPresenceOption, SingleValue: this.renderPresenceValue }} */} /> </div> <div className="username"> <p>{this.props.client.jid.local}</p> </div> </div> </div> )} </div> ); } } const mapStateToProps = (state, props) => ({ client: state.client, user: state.user, }); const mapDispatchToProps = (dispatch, props) => { return { setPresence: (presence) => dispatch(setPresence(presence)), }; }; export default connect(mapStateToProps, mapDispatchToProps)(UserInfo);
额外检查项
确保你的CSS中已经定义了对应状态的图标颜色:
.presenceIcon.available { color: #2ecc71; } .presenceIcon.dnd { color: #e74c3c; } .presenceIcon.away { color: #f39c12; }
内容的提问来源于stack exchange,提问作者Puneet Biswas
相关产品推荐
相关产品推荐

