En mi página, tengo dos elementos <select> , donde las opciones del segundo dependen del valor del primero.
En este caso, el "problema" es que las opciones para un determinado valor en la primera selección son diferentes de las opciones que se dan cuando la primera selección tiene otro valor. Básicamente:
Creé un violín simple solo para mostrarle el ejemplo y el problema: https://codesandbox.io/s/select-autochange-7bfj6
Por favor, abra la consola para ver de lo que estoy hablando. Entonces, básicamente, al inicio se seleccionan 'Porsche' y '911' . Entonces, si cambio '911' a 'Cayenne' todo está bien.
El problema es cuando cambio 'Porsche' a 'Alfa' : como debería ser, la segunda selección cambia su valor a 'Giulietta' , PERO el evento onChange de la segunda selección no se activa.
Estoy casi seguro de que el problema es algún tipo de desincronización entre la interfaz de usuario y el estado: en el estado, la segunda selección todavía tiene el valor '911' , pero como esa opción ya no está disponible en la segunda selección, selecciona automáticamente el primer valor posible... Pero esa autoselección es solo "gráfica".
Sé que esto podría solucionarse agregando un valor "nulo" en la segunda selección, con la opción <option value={''} label={'Select a Model'} /> . Pero me gustaría mantener la selección automática cuando cambie la primera selección.
EDITAR: en realidad, la solución que propuse no es una solución real: las opciones de 'seleccionar un modelo' tienen el valor '' , pero el handleSelectSelectChange aún no se activa, por lo tanto, mientras que el valor seleccionado de la interfaz de usuario es '' , en el estado I todavía tengo '911'
React.useEffect(()=> { if (!secondOptionsMemoized.some(x=> x === secondSelectValue)) { console.log('Second Select Change in useEffect'); setSecondSelectValue(secondOptionsMemoized[0]); } }, [secondSelectValue, secondOptionsMemoized]);Puede usar useEffect en lugar de useMemo y otro state que establezca las segundas opciones:
import React, { useEffect } from "react"; import "./styles.css"; export default function App() { const alfaForSecondOptions = ["Giulietta", "Mito"]; const otherForSecondOptions = ["Cayenne", "911"]; const [firstSelectValue, setFirstSelectValue] = React.useState("Porsche"); const [secondSelectValue, setSecondSelectValue] = React.useState("911"); const [secondOptions, setSecondOptions] = React.useState( otherForSecondOptions ); useEffect(() => { console.log(secondSelectValue); }, [secondOptions]); useEffect(() => { if (firstSelectValue === "Alfa") { setSecondOptions(alfaForSecondOptions); setSecondSelectValue("Giulietta"); } else { setSecondOptions(otherForSecondOptions); setSecondSelectValue("911"); } }, [firstSelectValue]); const handleFirstSelectChange = (e) => { console.log("First Select Change", e.target.value); setFirstSelectValue(e.target.value); }; const handleSecondSelectChange = (e) => { console.log("Second Select Change", e.target.value); setSecondSelectValue(e.target.value); }; return ( <div className="App"> <label> <p>Brand</p> <select onChange={handleFirstSelectChange} value={firstSelectValue}> <option value={"Alfa"} label={"Alfa"} /> <option value={"Porsche"} label={"Porsche"} /> </select> </label> <label> <p>Model</p> <select onChange={handleSecondSelectChange} value={secondSelectValue}> {secondOptions.map((x) => { return <option key={x} value={x} label={x} />; })} </select> </label> </div> ); }