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

React JS多级联动下拉框数据填充异常问题求助

Hey there! Let's fix those cascading dropdowns for you—your logic is on the right track, but there are a few key issues tripping things up. Let's break down the problems and walk through the corrected code.

First, let's identify the main issues in your code:

  • Mismatched data types in switch case: When you select an option from the first dropdown, e.target.value is a string (e.g., "2"), but your switch uses numeric cases like case 2. These won't match, so your fruit list never gets populated correctly.
  • Incorrect fruit list formatting: You're setting fruitList to a comma-separated string (like "Kiwi,Banana"), but your CreateOptions component uses Array.from() which splits the string into individual characters instead of separate options. You need to split the string into an array instead.
  • Redundant useEffect: The useEffect that just sets fruitList to itself is unnecessary and can cause unnecessary re-renders—we can remove it entirely.
  • Missing state for subsequent dropdowns: You haven't added state variables or change handlers for extraFlavor and recepieMenu, so those dropdowns never get populated.
  • Disabled state not implemented: Your initial requirement says only the first dropdown should be enabled at load, but none of the dropdowns have disabled attributes to enforce this.

Here's the corrected code with all fixes applied:

import React, { useState } from "react";

const ChooseTheFruit = () => {
  // Reusable component to create options
  function CreateOptions(props) {
    const data = Array.isArray(props.data) ? props.data : [];
    return data.map((item, index) => (
      <option key={index} value={item}>
        {item}
      </option>
    ));
  }

  // State variables for each dropdown
  const [idOptions] = useState([1, 2, 3, 4, 5]); // Fixed: idOptions is static, no need to update it
  const [selectedId, setSelectedId] = useState(""); // Track selected ID (string type)
  const [fruitList, setFruitList] = useState([]);
  const [extraFlavors, setExtraFlavors] = useState([]);
  const [selectedFruit, setSelectedFruit] = useState("");
  const [selectedFlavor, setSelectedFlavor] = useState("");
  const [recipes, setRecipes] = useState([]);

  // Populate fruit list when ID is selected
  const handleIdChange = (e) => {
    const currentID = e.target.value;
    setSelectedId(currentID);
    setSelectedFruit(""); // Reset fruit selection when ID changes
    setExtraFlavors([]); // Reset flavors when ID changes
    setRecipes([]); // Reset recipes when ID changes

    // Convert currentID to number for switch case, or use string cases
    switch (parseInt(currentID)) {
      case 1:
        setFruitList("Orange,Pineapple".split(","));
        break;
      case 2:
        setFruitList("Kiwi,Banana".split(","));
        break;
      case 3:
        setFruitList("Almond,Pistachio".split(",")); // Fixed typo here!
        break;
      case 4:
        setFruitList("Papaya,Mango".split(","));
        break;
      case 5:
        setFruitList("Muskmelon,Watermelon".split(",")); // Fixed typo here!
        break;
      default:
        setFruitList([]);
        break;
    }
  };

  // Populate extra flavors when fruit is selected
  const handleFruitChange = (e) => {
    const selected = e.target.value;
    setSelectedFruit(selected);
    setSelectedFlavor(""); // Reset flavor selection when fruit changes
    setRecipes([]); // Reset recipes when fruit changes

    // Example flavor data based on fruit
    switch (selected) {
      case "Orange":
        setExtraFlavors(["Vanilla", "Strawberry", "Chocolate"]);
        break;
      case "Banana":
        setExtraFlavors(["Peanut Butter", "Honey", "Cinnamon"]);
        break;
      case "Kiwi":
        setExtraFlavors(["Lime", "Coconut", "Mint"]);
        break;
      // Add more cases for other fruits as needed
      default:
        setExtraFlavors([]);
        break;
    }
  };

  // Populate recipes when flavor is selected
  const handleFlavorChange = (e) => {
    const selected = e.target.value;
    setSelectedFlavor(selected);

    // Example recipe data based on fruit + flavor
    const baseRecipe = `${selected} ${selectedFruit}`;
    setRecipes([
      `${baseRecipe} Shake`,
      `${baseRecipe} Ice Cream`,
      `${baseRecipe} Smoothie`,
    ]);
  };

  return (
    <>
      <div>
        <h3>Please choose the Fruit</h3>
        <br />
        {/* ID Dropdown: Always enabled */}
        <select id="myNumber" onChange={handleIdChange} value={selectedId}>
          <option value="">Select an ID</option> {/* Default empty option */}
          <CreateOptions data={idOptions} />
        </select>
        <br />
        {/* Fruit List: Enabled only when ID is selected */}
        <select
          id="fruitList"
          onChange={handleFruitChange}
          value={selectedFruit}
          disabled={!selectedId}
        >
          <option value="">Select a Fruit</option>
          <CreateOptions data={fruitList} />
        </select>
        <br />
        {/* Extra Flavor: Enabled only when fruit is selected */}
        <select
          id="extraFavourMenu"
          onChange={handleFlavorChange}
          value={selectedFlavor}
          disabled={!selectedFruit}
        >
          <option value="">Select a Flavor</option>
          <CreateOptions data={extraFlavors} />
        </select>
        <br />
        {/* Recipe Menu: Enabled only when flavor is selected */}
        <select
          id="recepieMenu"
          disabled={!selectedFlavor}
          value={""}
        >
          <option value="">Select a Recipe</option>
          <CreateOptions data={recipes} />
        </select>
        <br />
        <button disabled={!selectedFlavor}>Fetch Receipe</button>
      </div>
      <div id="receipe">here we will show recepie contents</div>
    </>
  );
};

export default ChooseTheFruit;

Key changes explained:

  1. Separated state for selected values: We now track selectedId, selectedFruit, and selectedFlavor separately from the option lists—this makes it easier to manage resets and disabled states.
  2. Fixed data type mismatch: We convert currentID to a number with parseInt() so the switch cases work correctly, or you could use string cases like case "2" instead.
  3. Properly formatted option lists: We use .split(",") to turn comma-separated strings into arrays of options, which CreateOptions can handle correctly.
  4. Added disabled attributes: Each dropdown is disabled until the previous one has a valid selection, matching your initial requirements.
  5. Added handlers for all dropdowns: handleFruitChange and handleFlavorChange populate the next dropdowns based on the current selection, and reset subsequent states when a parent selection changes.
  6. Fixed typos: Corrected "Almonda" → "Almond", "Pistachu" → "Pistachio", "Watermalon" → "Watermelon" for accuracy.
  7. Added default empty options: This makes it clearer to users what they need to select next, and prevents unexpected behavior.

Now your dropdowns should cascade correctly: select an ID → fruit list populates and enables → select a fruit → flavor list populates and enables → select a flavor → recipe list populates and enables the button.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 19:52:37