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

React Select多选下拉菜单失焦后状态变为undefined的问题求助

解决React-Select多选状态关闭菜单后丢失的问题

我来帮你搞定这个问题!你遇到的状态丢失问题,核心原因是更新状态时没有保留原有状态的属性。

问题根源

React的useState更新是替换式的,不像Class组件的setState会自动合并对象。你在onBlur和onFocus里直接传入新对象{ isFocused: false }或{ isFocused: true },这会完全覆盖之前的状态对象,导致原来的optionSelected属性被丢弃,所以关闭菜单后状态里的optionSelected就变成了undefined。

修复方案

更新状态时,要保留原有状态的所有属性,只修改需要更新的部分。可以用展开运算符结合函数式更新来实现:

  1. 修改onBlur和onFocus的状态更新逻辑:

    onBlur={() => {
      // 保留原有状态,只更新isFocused
      setSportsSelectorState(prevState => ({ ...prevState, isFocused: false }));
    }}
    onFocus={() => {
      setSportsSelectorState(prevState => ({ ...prevState, isFocused: true }));
    }}
    
  2. 同时,handleChange里的状态更新也建议用同样的方式,确保状态更新的安全性(避免依赖外部状态的旧值):

    function handleChange(selected) {
      setSportsSelectorState(prevState => ({
        ...prevState,
        optionSelected: selected
      }));
    }
    

修改后的完整代码

import React from "react";
import { default as ReactSelect } from "react-select";
import { components } from "react-select";

export default function BettingDeck(props) {
  const sportsOptions = [
    { value: "soccer", label: "Soccer" },
    { value: "dota", label: "Dota 2" },
    { value: "tennis", label: "Tennis" },
    { value: "csgo", label: "CS:GO" }
  ];

  const Option = (props) => {
    return (
      <div>
        <components.Option {...props}>
          <input type="checkbox" checked={props.isSelected} onChange={() => null} />{" "}
          <label>{props.label}</label>
        </components.Option>
      </div>
    );
  };

  const [sportsSelectorState, setSportsSelectorState] = React.useState({
    optionSelected: [],
    isFocused: true
  });

  function handleChange(selected) {
    setSportsSelectorState(prevState => ({
      ...prevState,
      optionSelected: selected
    }));
  }

  console.log(sportsSelectorState.optionSelected);

  return (
    <>
      <div className="betting-deck-container">
        <div className="betting-deck-head-container">
          <div className="betting-deck-title">Betting Deck</div>
          <span
            className="d-inline-block"
            data-toggle="popover"
            data-trigger="focus"
            data-content="Please selecet account(s)"
            onBlur={() => {
              setSportsSelectorState(prevState => ({ ...prevState, isFocused: false }));
            }}
            onFocus={() => {
              setSportsSelectorState(prevState => ({ ...prevState, isFocused: true }));
            }}
            style={
              sportsSelectorState.isFocused ? { zIndex: 1 } : { zIndex: 0 }
            }
          >
            <ReactSelect
              options={sportsOptions}
              isMulti
              closeMenuOnSelect={false}
              hideSelectedOptions={false}
              components={{ Option }}
              onChange={handleChange}
              allowSelectAll={true}
              value={sportsSelectorState.optionSelected}
              placeholder="Select sports to filter"
              menuPortalTarget={document.body}
              classNamePrefix="mySelect"
            />
          </span>
        </div>
      </div>
    </>
  );
}

这样修改后,关闭菜单时只会更新isFocused属性,optionSelected会被完整保留下来,状态就不会再丢失了。

内容的提问来源于stack exchange,提问作者Nikita Kulikov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 13:09:07