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

如何实现可复用的useState与处理函数,完成多组开关按钮且遵循DRY原则?

你可以把状态改成对象结构,用「组标识+选项值」的维度管理多组按钮的状态,只需要一个useState和一个通用处理函数就能完成,完全符合DRY原则:

实现思路

  1. 状态初始化时用对象存储,key对应不同的按钮组,value对应该组当前选中的选项
  2. 通用处理函数直接接收「组名」和「选中值」两个参数,不用依赖DOM的id属性,也不用写冗余的switch判断
  3. 如果需要新增按钮组,只需要在初始状态里加对应的组key即可,不用新增 useState 和处理函数

完整代码示例

import React, { useState } from "react";

const SettingXY = () => {
  // 单个useState管理所有按钮组状态,key对应不同组,value是当前选中值
  const [groupState, setGroupState] = useState({
    group1: undefined,
    group2: undefined
  });

  // 单个通用处理函数,接收组名和要设置的选中值
  const handleMenuShow = (groupName, value) => {
    setGroupState(prev => ({
      ...prev,
      [groupName]: value
    }));
  };

  // 抽成可复用的按钮组组件,进一步减少重复代码
  const ButtonGroup = ({ groupName }) => {
    const options = [
      { label: 'A setting', value: 1, text: 'This is A' },
      { label: 'B setting', value: 2, text: 'This is B' },
      { label: 'C setting', value: 3, text: 'This is C' },
      { label: 'D setting', value: 4, text: 'This is D' }
    ]
    return (
      <div>
        {options.map(opt => (
          <button 
            key={opt.value} 
            onClick={() => handleMenuShow(groupName, opt.value)}
          >
            {opt.label}
          </button>
        ))}
        <div>
          {options.map(opt => 
            groupState[groupName] === opt.value && 
            <div key={opt.value} state={opt.value}>{opt.text}</div>
          )}
        </div>
      </div>
    )
  }

  return (
    <div>
      {/* 第一组按钮 */}
      <ButtonGroup groupName="group1" />
      {/* 第二组按钮 */}
      <ButtonGroup groupName="group2" />
      {/* 后续新增任意组只要加一行代码,不用改其他逻辑 */}
      {/* <ButtonGroup groupName="group3" /> */}
    </div>
  );
};

export default SettingXY;

该方案全程只用到1个useState和1个处理函数,去掉了冗余的switch判断和重复的JSX代码,也避免了DOM id重复的潜在问题,后续扩展成本极低。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 18:24:03