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

如何在React中根据另一个下拉框动态改变下拉选项?

解决方案

要实现切换type下拉框时更新table_id的选项,核心是在type状态变化时触发接口请求,再用返回的数据更新菜单选项,具体步骤如下:

1. 监听type变化触发请求

修改原有的useEffect,将type加入依赖数组,这样每次type改变时都会重新执行请求逻辑:

const [menus, setMenus] = useState([]);

useEffect(() => {
  // 未选择type时不发起请求
  if (!type) return;
  
  async function fetchMenusByType() {
    try {
      // 调用根据type筛选菜单的接口(需确保menuservice提供此方法,或调整getAll接口支持传参)
      const result = await menuservice.getByType(type);
      setMenus(result.data);
      // 重置table_id,避免选中的id不在新选项中导致异常
      setTable_id(0);
    } catch (error) {
      console.error('加载菜单数据失败:', error);
    }
  }

  fetchMenusByType();
}, [type]); // 依赖type,状态变化时重新执行

如果你的getAll接口支持通过查询参数过滤类型,也可以改成:

const result = await menuservice.getAll({ type: type });

2. 优化下拉框渲染逻辑

在table_id的下拉框中,只有当menus有数据时才渲染选项,同时修正原代码中link输入框的id错误(原代码写的是name,会和第一个输入框冲突):

<select
  name="table_id"
  className="input"
  value={table_id}
  onChange={(e) => setTable_id(e.target.value)}
>
  <option disabled>--Chọn menu cha--</option>
  <option value="0">Không có cha</option>
  {menus.map((menu) => (
    <option key={menu.id} value={menu.id}>
      {menu.name}
    </option>
  ))}
</select>

完整修改后的组件代码

import { faBackward, faFloppyDisk } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Link, useNavigate } from "react-router-dom";
import { useEffect, useState } from "react";

import menuservice from "../../../services/MenuService";

function MenuCreate() {
  const navigate = useNavigate();
  const [name, setName] = useState("");
  const [link, setLink] = useState("");
  const [table_id, setTable_id] = useState(0);
  const [type, setType] = useState("");
  const [status, setStatus] = useState(1);
  const [menus, setMenus] = useState([]);

  async function postStore(event) {
    event.preventDefault();
    const image = document.querySelector("#image");
    var menu = new FormData();
    menu.append("name", name);
    menu.append("link", link);
    menu.append("table_id", table_id);
    menu.append("type", type);
    menu.append("status", status);
    menu.append("image", image.files[0]);

    try {
      const res = await menuservice.create(menu);
      alert(res.data.message);
      navigate("../../admin/menu", { replace: true });
    } catch (error) {
      console.error(error.response.data);
    }
  }

  useEffect(() => {
    if (!type) return;
    
    async function fetchMenusByType() {
      try {
        // 替换为你的实际接口调用逻辑
        const result = await menuservice.getByType(type);
        setMenus(result.data);
        setTable_id(0);
      } catch (error) {
        console.error('加载菜单数据失败:', error);
      }
    }

    fetchMenusByType();
  }, [type]);

  return (
    <section className="mainList">
      <div className="wrapper">
        <div className="card1">
          <form method="post" onSubmit={postStore}>
            <div className="card-header">
              <strong className="title1">THÊM MENU</strong>
              <div className="button">
                <Link to="/admin/menu" className="backward">
                  <FontAwesomeIcon icon={faBackward} />
                  Go back
                </Link>
                <button type="submit" className="save">
                  <FontAwesomeIcon icon={faFloppyDisk} />
                  Save
                </button>
              </div>
            </div>
            <div className="form-container grid -bottom-3  ">
              <div className="grid__item large--three-quarters">
                <fieldset className="input-container">
                  <label htmlFor="name">Tên menu</label>
                  <input
                    name="name"
                    type="text"
                    className="input"
                    id="name"
                    value={name}
                    onChange={(e) => setName(e.target.value)}
                    placeholder="Nhập tên menu..."
                  />
                </fieldset>
                <fieldset className="input-container">
                  <label htmlFor="link">Đường dẫn menu</label>
                  <input
                    name="link"
                    type="text"
                    className="input"
                    id="link"
                    value={link}
                    onChange={(e) => setLink(e.target.value)}
                    placeholder="Nhập đường dẫn..."
                  />
                </fieldset>
              </div>
              <div className="grid__item large--one-quarter">
                <fieldset className="input-container">
                  <label htmlFor="type">Chọn loại menu</label>
                  <select
                    name="type"
                    className="input"
                    value={type}
                    onChange={(e) => setType(e.target.value)}
                  >
                    <option value="">--Chọn loại menu--</option>
                    <option value="mainmenu">Menu chính</option>
                    <option value="footermenu">Menu footer</option>
                  </select>
                </fieldset>
                <fieldset className="input-container">
                  <label htmlFor="table_id">Chọn menu cha</label>
                  <select
                    name="table_id"
                    className="input"
                    value={table_id}
                    onChange={(e) => setTable_id(e.target.value)}
                  >
                    <option disabled>--Chọn menu cha--</option>
                    <option value="0">Không có cha</option>
                    {menus.map((menu) => (
                      <option key={menu.id} value={menu.id}>
                        {menu.name}
                      </option>
                    ))}
                  </select>
                </fieldset>
                <fieldset className="input-container">
                  <label htmlFor="status">Tình trạng xuất bản</label>
                  <select
                    name="status"
                    className="input"
                    value={status}
                    onChange={(e) => setStatus(e.target.value)}
                  >
                    <option disabled>--Chọn tình trạng xuất bản--</option>
                    <option value="1">Xuất bản</option>
                    <option value="2">Không xuất bản</option>
                  </select>
                </fieldset>
              </div>
            </div>
          </form>
        </div>
      </div>
    </section>
  );
}

export default MenuCreate;

额外提示

  • 如果menuservice没有提供按类型查询的方法,需要先在后端实现对应接口,再在前端封装调用逻辑
  • 可以添加加载状态(比如请求时显示加载动画),提升用户体验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 20:35:02