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

Next.js带Checkbox的搜索筛选组件问题:搜索后Checkbox失效

问题分析与修复方案

核心错误点

  1. 选中状态未持久化:checkedMember是组件内部普通数组,每次组件渲染(如搜索触发重渲染)都会被重置为空,导致选中状态丢失。
  2. 搜索过滤数据源错误:搜索时直接基于状态getMemberList过滤,多次搜索后会截断原始数据,无法还原完整列表。
  3. Checkbox语法错误:type="checked"是无效属性,正确应为type="checkbox"。
  4. Checkbox未绑定选中状态:搜索后重新渲染的Checkbox无法读取之前的选中状态,导致显示与实际选中情况不符。

修复后的完整代码

const MemberSearchFilter = () => { 
  const memberList = [
    { "member_id": "133", "name": "Deepak Ramnani", "checked": "false" },
    { "member_id": "116", "name": "Yash Chandhok", "checked": "false" },
    { "member_id": "115", "name": "Tonia Sehan", "checked": "false" },
    { "member_id": "101", "name": "Akanksha Garg", "checked": "false" },
  ];

  const [filteredMemberList, setFilteredMemberList] = useState(memberList);
  const [searchName, setSearchName] = useState("");
  // 用状态持久化选中的成员ID
  const [checkedMemberIds, setCheckedMemberIds] = useState([]);

  // 始终基于原始成员列表过滤,避免数据截断
  const onTypeFilterNonMemberHandler = (e) => {
    const textValue = e.target.value.toLowerCase();
    setSearchName(textValue);
    
    const results = memberList.filter(customer => 
      customer.name.toLowerCase().startsWith(textValue)
    );
    setFilteredMemberList(results);
  };

  // 通过状态更新函数处理选中/取消选中逻辑
  const onClickCheckboxHandler = (e) => {
    const memberId = e.target.value;
    setCheckedMemberIds(prevIds => {
      if (e.target.checked) {
        return [...prevIds, memberId];
      } else {
        return prevIds.filter(id => id !== memberId);
      }
    });
  };

  return (
    <>
      <div className="col-md-9">
        <input
          type="text"
          className="form-control w-3/6"
          style={{ width: "300px" }}
          placeholder="search by name"
          onChange={onTypeFilterNonMemberHandler}
        />
      </div>
      <div className="row">
        {filteredMemberList.map((list, index) => (
          <div className="col-md-12" key={list.member_id}> {/* 用唯一的member_id作为key,避免索引key的问题 */}
            <div className="border my-[5px] rounded-lg px-[10px] py-[5px] relative">
              <div className="flex align-center justify-center">
                <div className="specialist-infos w-100">
                  <div>
                    <h4
                      className="xs:text-[13px] text-[15px]"
                      style={{ color: "#702963" }}
                    >
                      {list.name}
                    </h4>
                    {/* 原始数据无current_organisation字段,暂时注释或补充数据 */}
                    {/* <p className="mb-0 text-[12px]">{list.current_organisation}</p> */}
                  </div>
                </div>
                <input
                  type="checkbox" {/* 修复type属性 */}
                  name={`sendToMember`}
                  className="radio_input"
                  id={list.member_id} {/* 用member_id作为id,避免重名问题 */}
                  value={list.member_id}
                  checked={checkedMemberIds.includes(list.member_id)} {/* 绑定选中状态 */}
                  onChange={onClickCheckboxHandler}
                />
              </div>
            </div>
          </div>
        ))}
      </div>
    </>
  );
};

额外优化点

  • 将状态变量getMemberList重命名为filteredMemberList,语义更清晰。
  • 使用member_id作为列表项的key,而非索引,避免列表项顺序变化时的渲染问题。
  • 简化onChange事件的写法,直接传递函数引用。

内容的提问来源于stack exchange,提问作者utkarsh tiwari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 23:02:29