禁用 Reactjs 中的依赖下拉选项

2024-02-21

我正在制作一个简单的反应应用程序,其中有一些下拉列表,其中一个依赖于另一个。

-> 这里下拉菜单 1 的值为游戏类型,例如Indoor and Outdoor.

-> 这里下拉菜单 2 的值为运动类型,例如Chess , Tennis and Football .

要求:

需要涵盖以下不同的用例,

应用场景:

-> 用户选择Indoor from 下拉菜单 1,然后在下拉菜单 2仅值Chess需要启用,其他需要启用 禁用。

-> 用户选择Outdoor from 下拉菜单 1,然后在下拉菜单 2仅值Tennis and Football需要启用并选择国际象棋 需要禁用。

反之亦然:

-> 用户选择Chess from 下拉菜单 2,然后在下拉菜单 1仅值Indoor需要启用,其他需要启用 禁用。

-> 用户选择Tennis or Football from 下拉菜单 2,然后在下拉菜单 1仅值Outdoor需要启用,其他需要禁用。

Here we provide option of allowClear https://ant.design/components/select/#Select-props so that user can reset their selection in any select box selection (the close icon) enter image description here and do the above mentioned scenario in any way like selecting option from first dropdown or in second dropdown based on which the another dropdown make the option enable or disable.

现在我有这样的数据并可以进行修改以达到预期的结果。

const data = {
  games: {
    type: [
      { id: 1, value: "Indoor", sportId: [2] },
      { id: 2, value: "Outdoor", sportId: [1, 3] }
    ],
    sport: [
      { id: 1, value: "Tennis", typeId: [2] },
      { id: 2, value: "Chess", typeId: [1] },
      { id: 3, value: "Football", typeId: [2] }
    ]
  }
}

属性名称可能会有所不同,所以我cannot依赖于代码中的硬编码/静态名称,例如data.games.type or data.games.sport.

因此我尝试使用动态方法,例如

{Object.entries(data.games).map((item, index) => {
        return (
          <div className="wrapper" key={index}>
            <h4> {item[0]} </h4>
            <Select
              defaultValue="selectType"
              onChange={handleChange}
              allowClear
            >
              <Option value="selectType"> Select {item[0]} </Option>
              {item[1].map((option, j) => (
                <Option key={j} value={option.value}>
                  {option.value}
                </Option>
              ))}
            </Select>
            <br />
          </div>
        );
 })}

Reactjs 沙箱:

注意:这些选项需要(仅)被禁用并且应该not从选择框中删除,因为用户可以清除任何选择框选择并 从任何下拉列表中选择值。

纯 JavaScript 方法:(忽略此 JS 示例中下拉列表的重置,该示例在清除图标(关闭图标)的帮助下在 ReactJS 中处理)

这里还有Pure JS(工作)方法尝试使用硬编码选择框,每个元素分别带有 id,并且每个元素中都有一些重复的代码addEventListener,

const data = {
  games: {
    type: [
      { id: 1, value: "Indoor", sportId: [2] },
      { id: 2, value: "Outdoor", sportId: [1, 3] }
    ],
    sport: [
      { id: 1, value: "Tennis", typeId: [2] },
      { id: 2, value: "Chess", typeId: [1] },
      { id: 3, value: "Football", typeId: [2] }
    ]
  }
}

const typeSelect = document.getElementById('type')
const sportSelect = document.getElementById('sport')

const createSelect = (values, select) => {
  values.forEach(t => {
    let opt = document.createElement('option')
    opt.value = t.id
    opt.text = t.value
    select.append(opt)
  })
}

createSelect(data.games.type, typeSelect)
createSelect(data.games.sport, sportSelect)

typeSelect.addEventListener('change', (e) => {
  const val = e.target.value
  const type = data.games.type.find(t => t.id == val)
  Array.from(sportSelect.querySelectorAll('option')).forEach(o => o.disabled = true)
  type.sportId.forEach(sId =>
    sportSelect.querySelector(`option[value="${sId}"]`).disabled = false)
})

sportSelect.addEventListener('change', (e) => {
  const val = e.target.value
  const sport = data.games.sport.find(s => s.id == val)
  Array.from(typeSelect.querySelectorAll('option')).forEach(o => o.disabled = true)
  sport.typeId.forEach(sId =>
    typeSelect.querySelector(`option[value="${sport.typeId}"]`).disabled = false)
})
<select id="type"></select>
<select id="sport"></select>

您能帮我实现以下结果吗禁用相应的选项根据上述场景中提到的条件从相应的选择框中纯反应js way?

对于@Andy给出的评论,我正在使用的选择中有一个重置选项可用,关闭图标,因此使用该用户可以清除选择框并选择其他下拉选项。该选项在下面提供允许清除 https://ant.design/components/select/#Select-props in the antd选择 https://ant.design/components/select。请查看我在上面的代码和框中的选择框,它在最后有清晰的图标。


根据我对你的问题的理解,这是我的可行解决方案。您需要能够轻松地针对其他动态选项进行验证的动态选项。这是我能想到的最好的方案,但也不是完全无法维护。大约 98% 是动态的,但出于验证目的,有些属性do需要定义。

Example:

设置接口和类型

interface IState { // <-- need to be known
  type: number;
  sport: number;
}

interface IOption {
  id: number;
  value: string;
  valid: Record<keyof IState, number[]>;
}

type Valid = "sport" & "type"; // <-- this needs to be known

interface Data {
  games: {
    [key: string]: Array<Record<Valid, IOption[]>>;
  };
}

Data

const data: Data = {
  games: {
    type: [
      { id: 1, value: "Indoor", valid: { sport: [2] } },
      { id: 2, value: "Outdoor", valid: { sport: [1, 3] } }
    ],
    sport: [
      { id: 1, value: "Tennis", valid: { type: [2] } },
      { id: 2, value: "Chess", valid: { type: [1] } },
      { id: 3, value: "Football", valid: { type: [2] } }
    ],
  }
};

创建组件状态以保存选定的选项值。这些应该与数据中已知的选择类型相匹配。这里的想法是,我们现在将选择输入转换为受控输入,以便我们可以根据所选状态验证选项。

export default function App() {
  const [state, setState] = React.useState<IState>({
    type: -1,
    sport: -1,
    category: -1
  });

  const changeHandler = (key: keyof IState) => (value: number) => {
    setState((state) => ({
      ...state,
      [key]: value
    }));
  };

这是添加的重点。根据数据配置针对当前选定的状态值验证选项。查看每个选项的valid对象并与当前选定的状态进行比较。返回当前选项是否是有效的可选选项。

  const isValid = (key: keyof IState, option: IOption) => {
    const { valid } = option;

    return (Object.entries(valid) as [[keyof IState, number[]]]).every(
      ([validKey, validValues]) => {
        const selectedValue = state[validKey];
        if (!selectedValue || selectedValue === -1) return true;

        return validValues.includes(state[validKey]);
      }
    );
  };

  return (
    <>
      <br />
      {(Object.entries(data.games) as [[keyof IState, IOption[]]]).map(
        ([key, options]) => {
          return (
            <div className="wrapper" key={key}>
              <h4>{key}</h4>
              <Select
                value={state[key] || -1}
                onChange={changeHandler(key)}
                allowClear
              >
                <Option disabled value={-1}>
                  Select {key}
                </Option>
                {options.map((option) => (
                  <Option
                    key={option.id}
                    value={option.id}
                    disabled={!isValid(key, option)} // if not valid, then disable
                  >
                    {option.value}
                  </Option>
                ))}
              </Select>
              <br />
            </div>
          );
        }
      )}
    </>
  );
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

禁用 Reactjs 中的依赖下拉选项 的相关文章

  • Heroku 上重启后 Better-SQLite3 数据库重置

    我有一个 Discord 机器人better sqlite3 https github com JoshuaWise better sqlite3硬币和 XP 数据库 直到两周前它一直工作得很好 现在 每次重新启动后 它只会恢复 XP 和硬
  • 在 BEFORE INSERT 触发器中使用 IF EXISTS (SELECT ...) (Oracle)

    我的代码不起作用 Oracle 告诉我创建触发器时出现构建错误 显然我无法获得有关构建错误的更准确信息 我以前确实没有做过很多SQL 所以我对语法不太熟悉 我有一种预感 Oracle 不喜欢我的 IF EXISTS SELECT THEN
  • 在 Node.js 中实现服务器发送事件的简单方法?

    我环顾四周 似乎在 Node js 中实现 SSE 的所有方法都是通过更复杂的代码 但似乎应该有一种更简单的方法来发送和接收 SSE 是否有任何 API 或模块可以让这件事变得更简单 这是一个每秒发送一个服务器发送事件 SSE 的 Expr
  • Google javascript 登录 api:无法离线访问

    我正在尝试为服务器端应用程序实现 Google 登录 如 Google 文档中所示 服务器端应用程序的 Google 登录 https developers google com identity sign in web server si
  • webrtc - 获取网络摄像头的宽高比

    我正在尝试学习如何开发 webRTC 应用程序 我想知道是否可以获得相机的宽高比 我不知道它是否有帮助 但我正在使用 webrtc io 但是 if更好 我可以停止使用它 From MDN https developer mozilla o
  • 确定用户是否在shadow dom之外单击

    我正在尝试实现一个下拉菜单 您可以单击外部将其关闭 下拉列表是自定义日期输入的一部分 并且封装在输入的影子 DOM 内 我想写一些类似的东西 window addEventListener mousedown function evt if
  • 如何在没有数据库的情况下创建AJAX分页?

    是否可以在没有 MySQL 帮助的情况下获取 AJAX 分页页面 难道我不能只添加一个包含我需要显示的文本和标记的 PHP 文件 然后通过单击页码将该内容提供给用户吗 那么可以用纯 jQuery 和 PHP 来实现吗 您会使用什么代码方法来
  • React Router 总是将我重定向到不同的 url

    我是 React 和 React Router 的新手 我正在使用 React Router v4 并遵循基于以前版本的教程 但我让它工作了 使用在 SO 上找到的一些东西和 React Router v4 文档上的一些东西 但有一件事困扰
  • 如何在正则表达式中区分数字和ip地址?

    例如 如果我们查看 5 56 和 183 55 0 144 基本上 当你做这样的事情时 d d 它匹配 5 56 189 55 和 0 144 有没有办法通过正则表达式仅匹配数字而不匹配 ip 地址的部分 我尝试使用前瞻 但我不知道它应该是
  • Ember:命名出口错误

    我不知道为什么我的模板没有在指定的插座中呈现 这是我第一次尝试学习 ember 我被困在指定的渠道上 我想渲染侧边栏模板 in the outlet sidebar 和内容模板 in the outlet content 但我不断在控制台中
  • 如何在React中处理多个路由器

    假设我们有一个网络应用程序 它通常有很多视图 例如索引页面 管理面板 帮助页面 联系人等 我在主index js 中使用react router dom 来处理它们 它工作得很好 但是现在我在开发管理面板时遇到了问题 它是 index js
  • 在流星收集加载时显示加载程序

    我有一个模板 task list 看起来像这样 each tasks gt task each Template task list tasks返回一个集合 在用户界面中 加载似乎需要一些时间 当集合正在加载时 我想显示一个加载指示器 关于
  • 从数据库中给定时间起经过的时间

    我有一个 HTML 表 其中包含从数据库中提取的记录 我正在使用 PHP MySQL 我的表中名为 Timer 的列未从数据库中检索 我需要在此处显示经过的时间 从数据库中的特定时间开始 例如 假设现在的时间是2013年2月21日下午6点2
  • jqPlot DateAxis tickInterval 不起作用

    我试图每月绘制一个包含单个数据点的图表 我会在每个月的第一天将其作为一个点发送到 jqPlot jqplot actualChart 2011 10 01 0 296 2011 11 01 0 682 title programSelect
  • 访问事件处理程序内的对象实例

    我有以下代码 var myObj inputs document getElementsByTagName input attachKeyEvent function for var i 0 i lt this inputs length
  • 使用 Lodash 循环 JavaScript 对象中的属性

    是否可以循环访问 JavaScript 对象中的属性 例如 我有一个 JavaScript 对象定义如下 myObject options property1 value 1 property2 value 2 属性将动态添加到该对象 有没
  • 发生错误。", ExceptionMessage: "提供的 'HttpContent' 实例无效

    尝试将文件添加到 http 休息调用时出现此错误 responseJson 消息 发生错误 ExceptionMessage 提供了无效的 HttpContent 实例 它确实 正在使用 多部分 参数名称 内容 异常类型 System Ar
  • 谷歌浏览器不显示一个网站的alert()弹出窗口

    我正在开发一个 javascript 循环 该循环会随着循环的进行而提醒每个键值 为了加快速度 我选中了 阻止此页面创建其他对话框 框 通常这只会抑制一个例程的弹出窗口 但它们还没有回来 在 Google Chrome 中 alert 消息
  • 我应该采取什么圆角方法?

    因此 关于圆角的信息并不缺乏 我已经经历过其中的大部分 我发帖是为了征求社区对这一点的意见 我的场景是 我们正在开发一个圆角相关设计 主要用于交互
  • 如何连接/组合两个数组以连接成一个数组?

    我正在尝试将 JavaScript 中的 2 个数组合并为一个 var lines new Array a b c lines new Array d e f 这是一个简单的例子 我希望能够将它们组合起来 这样当读取第二行时 数组中的第四个

随机推荐

  • css 媒体查询将类添加到 HTML

    我有这个 HTML li a href i class fa fa iconname i Link Name a li 然后我在 CSS 中使用这个媒体查询 media max width 1000px 我怎样才能将我的标签更改为 i cl
  • 将 flow.js 上传到 Node/express 服务器后重新组装二进制文件

    我不知道如何将 flow js 库与节点后端一起使用 并将我的代码基于示例flow js https github com flowjs flow js blob master samples Node js flow node js gi
  • 如何使用 Firebase 托管记录已部署的 Angular Web 应用程序的错误

    我正在开发一个 Angular 单页 Web 应用程序 它使用 Firestore 作为数据库 并将部署到 Firebase 托管 除非您正在开发 Android 或 iOS 移动应用程序 否则似乎没有内置方法可以将错误记录到服务器或获取运
  • “显示:内联块”技巧在 Firefox 中不起作用

    我想要创建的是一个整页网站 没有滚动条 其中包含垂直和水平居中的文本 图像 div 块 我研究并使用了一种技术 使用 100 高度的 div 和 0px 宽度 然后使用内容 div 来垂直居中内容 在 safari 中工作完美 在 fire
  • XNA 模拟 Game 对象或解耦您的 Game

    我想知道是否可以模拟 Game 对象来测试我的 Drawable Game Component 组件 我知道模拟框架需要一个接口才能运行 但我需要模拟实际的Game http msdn microsoft com en us library
  • 在 iOS 8 Beacon 中未检测到

    iBeacon 在 iOS8 中突然停止工作 之前它在之前的 iOS 8 版本中运行良好 有人帮助我摆脱这个问题吗 请问是什么问题 谢谢 您需要做的是在代码中添加访问位置服务的请求权限 如下所示 if self locationManage
  • 如何在CXF中使用PATCH方法

    我正在尝试使用 JAX RS 的 CXF 实现在我的客户端中使用 PATCH 方法 起初我将 PATCH 注释定义为 Target ElementType METHOD Retention RetentionPolicy RUNTIME H
  • C 与 C++ 中的 typedef 和 struct 命名空间

    我正在尝试在一些新的 C 中使用一些旧的 C 库 该库的头文件使用 D Hanson 的 C 接口和实现 https rads stackoverflow com amzn click com 0201498413隐藏实现的习惯用法 def
  • 将元素替换为outerHTML并立即访问新创建的元素

    我通过将 DOM 元素的内容替换为outerHTML 这个技巧有效 但我需要立即访问新创建的 DOM 元素 不幸的是元素的创建
  • 有没有办法只获取未命名的参数?

    在 JavaScript 函数中 arguments https developer mozilla org en US docs Web JavaScript Reference Functions and function scope
  • 为 ggplot2 中的两个构面组指定不同的 x-tick 标签

    我有代表两种方法结果的箱线图 每种方法都有两种验证方法和三种场景 使用 ggplot2 进行绘制 一切正常 但我想更改 x 轴刻度标签以区分每组中使用的技术类型 我使用了以下代码 data lt read csv results csv h
  • Laravel 和 Eloquent:检索相关项目时指定列

    这是以下帖子的后续帖子 Laravel 4 和 Eloquent 检索所有记录和所有相关记录 https stackoverflow com questions 21735011 laravel 4 and eloquent retriev
  • 从 iOS 服务检测屏幕开/关

    我正在开发一个作为服务在后台运行的网络监控应用程序 当屏幕打开或关闭时是否可以收到通知 来电 它通过使用以下代码存在于Android中 private void registerScreenOnOffReceiver IntentFilte
  • 使用nodejs进行heroku部署失败

    我正在尝试将本地文件推送到 heroku 并遇到以下错误 我的代码在github https github com asimkh apps tree haz 有人可以帮我吗 谢谢 heroku buildpacks set heroku n
  • 如何检测 STAMINA 模式?

    您能帮助我 如何以编程方式检测索尼设备上的 STAMINA 模式吗 我想通知用户 如果 STAMINA 打开 我的应用程序将无法正常工作 因为它阻止了 AlarmManager 并且设备在我需要时不会被唤醒 我也想知道这个 我想一个天真的方
  • Flask WTform 对多个字段进行验证

    根据两个或多个条目验证 WTform 的最佳方法是什么 IE 在下面的表格中 我想验证数据库中尚不存在具有所提供名称和地址的公司 class CompanyForm FlaskForm name StringField Company Na
  • 如何在bash中生成笛卡尔积?

    我想生成这样的文件 笛卡尔积 1 3 X 1 5 1 1 1 2 1 3 1 4 1 5 2 1 2 2 2 3 2 4 2 5 3 1 3 2 3 3 3 4 3 5 我可以使用嵌套循环来做到这一点 例如 for i in seq 3 d
  • 无法执行dex:Java堆空间 Java堆空间

    在 Eclipse IDE 中执行 Web 驱动程序脚本时 出现 Unable toexecute dex Java heap space Java heap space 错误 我已经使用 Android SDK 和 AVD Manager
  • Java 流压缩两个列表

    我有一个人员哈希集 一个人有名字 姓氏和年龄 例如 Person Hans Man 36 我的任务是获取 17 岁以上人员的列表 按年龄对他们进行排序 并将名字与姓氏连接起来 比如 汉斯 曼 另一个名字 另一个名字 我刚刚被允许导入 imp
  • 禁用 Reactjs 中的依赖下拉选项

    我正在制作一个简单的反应应用程序 其中有一些下拉列表 其中一个依赖于另一个 gt 这里下拉菜单 1 的值为游戏类型 例如Indoor and Outdoor gt 这里下拉菜单 2 的值为运动类型 例如Chess Tennis and Fo