You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React多选下拉框搜索后选中状态异常问题排查

带搜索功能的多选下拉框组件异常问题

我正在开发一个带搜索功能的多选下拉框组件,大部分功能正常,但存在一个问题:

  • 初始选择“1”和“3”后,输入框能正确展示已选状态
  • 当搜索包含数字“4”的选项时,选项“4”会被自动选中,可我实际只选了“1”和“3”

以下是组件核心代码(已移除Tailwind样式及无关函数):

"use client"
import React, { useEffect, useId, useState } from "react"

export default function Cscheckdropdown(props: Props) {

    const inputText = useId()
    const inputSearch = useId()

    const [value, setValue] = useState < string[] > ([])
    const [searchValue, setSearchValue] = useState("")
    const [optionsFiltered, setOptionsFiltered] = useState(props.options.map((option) => { return option }))

    const handleSetValue = (e: React.MouseEvent<HTMLInputElement>) => {
        const valor = e.currentTarget.value

        if (!value.includes(valor)) {
            setValue([...value, valor])
        }
        else if (value.includes(valor)) {
            setValue(value.filter(v => v != valor))
        }
    }

    useEffect(() => {
        setOptionsFiltered(
            props.options.filter((x) => {
                if (x.includes((searchValue))) {
                    return x
                }
            })
        )
    }, [props.options, searchValue])

    return (<>
        <div>
            <input id={inputSearch} name={props.name + "_inputSearch"} type="text" onChange={(e) => { setSearchValue(e.currentTarget.value) }} value={searchValue} />
        </div>
        {
            optionsFiltered.map((option, index) => {
                return (
                    <div key={index}>
                        <label htmlFor={inputText + index}>
                            <input type="checkbox" id={inputText + index} name={props.name} value={option} onClick={handleSetValue} />
                            {option}
                        </label>
                    </div>
                )
            })
        }
    </>)
}

问题根源

  1. 复选框未受控:代码里的复选框没有绑定checked属性,React无法跟踪其选中状态。当搜索过滤导致组件重渲染时,浏览器会复用DOM元素,出现状态错乱。
  2. key值不合理:使用数组index作为key,过滤后选项顺序变化时,React会错误复用旧组件的状态,导致未选择的选项被自动选中。

修复方案

1. 让复选框成为受控组件

给每个复选框添加checked属性,绑定到已选数组value是否包含当前选项:

<input 
  type="checkbox" 
  id={inputText + option} 
  name={props.name} 
  value={option} 
  onClick={handleSetValue}
  checked={value.includes(option)} // 新增:绑定选中状态
/>

2. 替换key值为唯一标识符

将key从index改为option(确保所有选项值唯一),避免React复用错误的组件状态:

<div key={option}> {/* 替换index为option */}
  <label htmlFor={inputText + option}>
    {/* 复选框代码 */}
  </label>
</div>

3. 简化过滤逻辑(可选)

原过滤函数可以简化为直接返回布尔值,代码更简洁:

useEffect(() => {
  setOptionsFiltered(
    props.options.filter(x => x.includes(searchValue))
  )
}, [props.options, searchValue])

内容的提问来源于stack exchange,提问作者Thiago Barboza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 17:45:12