React中选中SelectItem时如何修改SelectValue的字体粗细?
解决React自定义Select组件的选中状态更新与TypeScript类型问题
一、补全TypeScript类型定义
TS报错的核心是自定义组件未声明对应props类型,先给三个组件定义清晰的Props接口:
// Select组件的Props interface SelectProps { selectedValue?: string; onChange: (value: string) => void; children: React.ReactNode; } // SelectItem组件的Props interface SelectItemProps { value: string; children: React.ReactNode; onClick?: () => void; } // SelectValue组件的Props interface SelectValueProps { placeholder: string; selectedValue?: string; }
二、修复SelectItem onClick不触发问题
问题通常是SelectItem未正确绑定点击事件,或父组件未传递回调。通过在Select组件内部克隆子元素,给每个SelectItem绑定点击逻辑:
const Select: React.FC<SelectProps> = ({ selectedValue, onChange, children }) => { return ( <div className="select-container"> <SelectValue placeholder="Select" selectedValue={selectedValue} /> <div className="select-dropdown"> {React.Children.map(children, child => { // 仅处理SelectItem类型的子元素 if (React.isValidElement(child) && child.type === SelectItem) { return React.cloneElement(child, { // 绑定点击事件,触发父组件onChange更新选中值 onClick: () => onChange(child.props.value) }); } return child; })} </div> </div> ); }; const SelectItem: React.FC<SelectItemProps> = ({ value, children, onClick }) => { // 直接绑定onClick到可点击容器,确保事件触发 return ( <div className="select-item" onClick={onClick} style={{ cursor: 'pointer', padding: '8px' }} role="option" tabIndex={0} > {children} </div> ); };
三、实现选中后SelectValue字体加粗
通过selectedValue是否存在动态控制字体粗细,无需额外维护isSelected状态:
const SelectValue: React.FC<SelectValueProps> = ({ placeholder, selectedValue }) => { const displayText = selectedValue || placeholder; // 有选中值时设为粗体,否则用常规字体 const fontWeight = selectedValue ? 'bold' : 'normal'; return ( <div className="select-value" style={{ fontWeight, padding: '8px', border: '1px solid #ccc', borderRadius: '4px' }} > {displayText} </div> ); };
父组件使用示例
import { useState } from 'react'; const App: React.FC = () => { const [selectedValue, setSelectedValue] = useState<string | undefined>(); return ( <div style={{ margin: '20px' }}> <Select selectedValue={selectedValue} onChange={setSelectedValue}> <SelectItem value="TO:">TO:</SelectItem> <SelectItem value="CC:">CC:</SelectItem> <SelectItem value="BCC:">BCC:</SelectItem> </Select> </div> ); };
关键注意点
- 不要在SelectItem内部调用
event.stopPropagation(),否则会阻止点击事件向上传递; - 给SelectItem添加
role="option"和tabIndex是为了满足无障碍访问要求; - 若需管理下拉框展开/收起状态,可在Select组件内部用
useState控制显示隐藏。
内容的提问来源于stack exchange,提问作者Kadie
相关产品推荐
相关产品推荐

