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.valueis a string (e.g., "2"), but your switch uses numeric cases likecase 2. These won't match, so your fruit list never gets populated correctly. - Incorrect fruit list formatting: You're setting
fruitListto a comma-separated string (like "Kiwi,Banana"), but yourCreateOptionscomponent usesArray.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
useEffectthat just setsfruitListto 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
extraFlavorandrecepieMenu, 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
disabledattributes 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:
- Separated state for selected values: We now track
selectedId,selectedFruit, andselectedFlavorseparately from the option lists—this makes it easier to manage resets and disabled states. - Fixed data type mismatch: We convert
currentIDto a number withparseInt()so the switch cases work correctly, or you could use string cases likecase "2"instead. - Properly formatted option lists: We use
.split(",")to turn comma-separated strings into arrays of options, whichCreateOptionscan handle correctly. - Added disabled attributes: Each dropdown is disabled until the previous one has a valid selection, matching your initial requirements.
- Added handlers for all dropdowns:
handleFruitChangeandhandleFlavorChangepopulate the next dropdowns based on the current selection, and reset subsequent states when a parent selection changes. - Fixed typos: Corrected "Almonda" → "Almond", "Pistachu" → "Pistachio", "Watermalon" → "Watermelon" for accuracy.
- 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
相关产品推荐
相关产品推荐

