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

React Select组件值显示与localStorage持久化问题求助

问题解决方案

问题1:选择0时未显示❌

原因

select组件的value属性是数字类型的0,但对应option的value被设置为字符串"0",React的下拉选择器采用严格类型匹配,导致选中状态不对应,无法正确渲染❌。

修复方案

统一select和option的value类型,同时修正空值判断逻辑(避免0被误判为空):

const SelectField: React.FC<SelectFieldProps> = ({diceOptions, onOptionChange, selectedOptions}) => {
  return(
    <div className={Style.container}>
      {diceOptions.map((diceOption: DiceType, index: number) => {
        return (
          <select
            key={`${diceOption.id}-${index}`}
            className={Style.select}
            onChange={(e) => {
              const value = e.target.value === "" ? "" : Number(e.target.value);
              onOptionChange(diceOption.id, value);
            }}
            // 用空值合并运算符替代逻辑或,避免0被转为空字符串
            value={selectedOptions[diceOption.id][0] ?? ""}
          >
            {diceOption.values.map((value: number | "", index: number) => {
              return (
                // 直接使用原始value,无需转换为字符串"0"
                <option key={index} value={value}>
                  {value === 0 ? "\u{274C}" : value}
                </option>
              )
            })}
          </select>
        )
      })}
    </div>
  )
}

问题2:切回空值后localStorage仍保留0值

原因

  1. Reducer的replace动作未正确处理空值场景,没有将对应ID的状态更新为空字符串;
  2. localStorage同步逻辑未过滤空值或未正确更新空值状态。

修复方案

1. 修正Reducer逻辑

确保空值传入时,将对应ID的状态设为空字符串:

const optionReducer = (state: StateType, action: ActionType): StateType => {
  switch (action.type) {
    case 'replace':
      if (!action.id || action.value === undefined) return state;
      return {
        ...state,
        // 直接赋值传入的value,空值会被保留为""
        [action.id]: [action.value]
      };
    case 'clear':
      return {};
    default:
      return state;
  }
};

2. 同步localStorage时过滤空值

如果不需要在localStorage中保留空值的键,可在存储前过滤:

const App: React.FC = () => {
  const [state, dispatch] = useReducer(optionReducer, initialState);

  // 监听state变化,同步到localStorage
  useEffect(() => {
    const filteredState = Object.fromEntries(
      Object.entries(state).filter(([_, value]) => value[0] !== "")
    );
    localStorage.setItem('selectedOptions', JSON.stringify(filteredState));
  }, [state]);

  const handleSelectChange = (id: string, value: number | ''):void => {
    dispatch({type: 'replace', id, value });
  }

  return (
    <>
      <SelectField diceOptions={diceOptions} onOptionChange={handleSelectChange} selectedOptions={state}/>
      <button onClick={() => clearLocalStorage(dispatch)}>Clear storage</button>
    </>
  )
}

内容的提问来源于stack exchange,提问作者Varikash Nikolay

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 20:55:31