如何在react-select中根据条件设置嵌套选项样式?
问题
我的<Select/>组件使用了嵌套选项,希望在选项被选中时移除选中标签<span>{tag}</span>的font-semibold和indent-2类。官方文档仅提供了普通选项的实现方法,但未提及嵌套选项的处理方式,请问该如何实现?
原组件代码:
<Select id="custom" name="custom" options={_.chain(customOptions) .map(op1 => ({ label: ( <div className="flex items-center justify-between text-sm font-semibold" > <span> {op1.title} </span> </div> ), options: _.map(op1.tags, tag => ({ label: ( <div className="mx-2 flex items-center justify-between" > <span className="font-semibold indent-2"> {tag} </span> </div> ), value: tag, group: op1, })), })) .value()} placeholder="Select Option" menuPortalTarget={document.body} type="default" styles={{ menuPortal: (base: any) => ({ ...base, zIndex: 9999 }), }} />
解决方案
方案1:通过styles属性全局覆盖选中样式
直接利用组件的styles配置,针对选中状态的选项元素覆盖样式,抵消font-semibold和indent-2的效果:
<Select id="custom" name="custom" options={_.chain(customOptions) .map(op1 => ({ label: ( <div className="flex items-center justify-between text-sm font-semibold" > <span> {op1.title} </span> </div> ), options: _.map(op1.tags, tag => ({ label: ( <div className="mx-2 flex items-center justify-between" > <span className="font-semibold indent-2"> {tag} </span> </div> ), value: tag, group: op1, })), })) .value()} placeholder="Select Option" menuPortalTarget={document.body} type="default" styles={{ menuPortal: (base: any) => ({ ...base, zIndex: 9999 }), option: (base: any, state: any) => ({ ...base, '& span': { // 选中时移除加粗和缩进 ...(state.isSelected && { fontWeight: 'normal', textIndent: 0, }), }, }), }} />
方案2:通过状态动态控制类名
维护当前选中值的状态,渲染选项标签时判断是否为选中项,动态切换类名:
import { useState } from 'react'; // 组件内部逻辑 const [selectedVal, setSelectedVal] = useState(null); return ( <Select id="custom" name="custom" value={selectedVal} onChange={(val) => setSelectedVal(val)} options={_.chain(customOptions) .map(op1 => ({ label: ( <div className="flex items-center justify-between text-sm font-semibold" > <span> {op1.title} </span> </div> ), options: _.map(op1.tags, tag => ({ label: ( <div className="mx-2 flex items-center justify-between" > <span className={selectedVal === tag ? '' : 'font-semibold indent-2'}> {tag} </span> </div> ), value: tag, group: op1, })), })) .value()} placeholder="Select Option" menuPortalTarget={document.body} type="default" styles={{ menuPortal: (base: any) => ({ ...base, zIndex: 9999 }), }} /> );
方案对比
- 方案1无需额外状态,通过组件内置的样式回调实现,适合全局统一修改;
- 方案2更灵活,可针对单个标签做精细的类名控制,适合需要自定义更多状态样式的场景。
内容的提问来源于stack exchange,提问作者xqcccccccccc
相关产品推荐
相关产品推荐

