如何为下拉列表选中项添加MUI/Tailwind CSS勾选图标?
实现下拉列表选中项显示勾选图标
问题分析
要实现多选下拉列表中已选中项旁显示勾选图标,需解决两个核心问题:
- 原生
<select>默认是单选模式,需开启多选模式 - 修正选中值的同步逻辑和图标渲染逻辑
修改方案
1. 修正CreateEvent组件的选中值更新逻辑
原逻辑仅处理添加选中值,未支持取消选中,需修改为根据多选状态动态更新数组:
import axios from "axios"; import React, { useState } from "react"; import TopicList from "../Components/topicList"; import CheckIcon from '@mui/icons-material/Check'; import { useNavigate } from "react-router-dom"; import { toast } from "react-toastify"; function CreateEvent() { const navigate = useNavigate(); const [selectedValues, setSelectedValues] = useState([]); // 支持添加/取消选中值的回调函数 const handleTopicSelect = (selectedOptions) => { const newSelectedValues = Array.from(selectedOptions) .map(opt => opt.value) .filter(val => val !== ""); setSelectedValues(newSelectedValues); }; const handleSubmit = (event) => { event.preventDefault(); console.log(selectedValues); axios({ method: "POST", url: process.env.REACT_APP_BASE_URL + "events/submitEvent", data: { topicId: selectedValues, }, headers: { "Content-Type": "application/json" }, }) .then((response) => { if (response.status === 200) { toast.success("Successfully Created", { position: toast.POSITION.TOP_CENTER, }); } else { toast.error(response.data.message, { position: toast.POSITION.TOP_CENTER, }); } }) .catch((err) => { if (err.response) { toast.error(err.response.data.message, { position: toast.POSITION.TOP_CENTER, }); } else { toast.error("Failed to Create", { position: toast.POSITION.TOP_CENTER, }); } }); }; return ( <div className=""> <div> <form onSubmit={handleSubmit}> <h1>Create an Event</h1> <div> <div> <TopicList selectedValues={selectedValues} onTopicSelect={handleTopicSelect} /> </div> </div> </form> </div> </div> ); } export default CreateEvent;
2. 修改TopicList组件开启多选并修正渲染逻辑
- 给
<select>添加multiple属性开启多选 - 修正
onChange事件处理,传递选中的所有option元素给父组件 - 确保勾选图标仅在当前项被选中时显示
import axios from "axios"; import React from "react"; import CheckIcon from "@mui/icons-material/Check"; const BASE_URL = process.env.REACT_APP_BASE_URL; export default class TopicList extends React.Component { state = { topics: [], }; componentDidMount() { axios.get(BASE_URL + `events/topic`).then((res) => { const topics = res.data; this.setState({ topics }); }); } render() { return ( {/* 添加multiple开启多选,size控制下拉框显示行数 */} <select required multiple size={5} onChange={(e) => this.props.onTopicSelect(e.target.selectedOptions)} > {this.state.topics.map((topic) => ( <option key={topic.topicId} value={topic.topicId} selected={this.props.selectedValues.includes(topic.topicId)} > {topic.topic} {/* 选中时显示绿色勾选图标 */} {this.props.selectedValues.includes(topic.topicId) && ( <CheckIcon style={{ color: "green", marginLeft: "8px" }} /> )} </option> ))} </select> ); } }
关键修改点说明
- 多选模式开启:通过
multiple属性启用多选,size属性控制下拉框默认显示的选项行数 - 选中值同步:父组件通过
onTopicSelect接收所有选中的option元素,提取topicId更新状态数组 - 图标渲染逻辑:通过
selectedValues.includes(topic.topicId)判断当前项是否被选中,动态渲染勾选图标 - 选中状态保持:给
<option>添加selected属性,确保组件重新渲染时已选中项保持高亮
内容的提问来源于stack exchange,提问作者jack
相关产品推荐
相关产品推荐

