Tengo este esquema de mangosta
const storeSchema = mongoose.Schema({ name: { type: String, required: true, }, fruits: { type: [String], required: true, }, });En mi lado del cliente, estoy haciendo esto para la entrada del nombre, y hasta ahora está funcionando.
const [store, setStoreData] = useState({ store: '', fruits: [''], }); const dispatch = useDispatch(); const handleSubmit = (e) => { e.preventDefault(); dispatch(addStore(store)); }; ... <TextField label='Store Name' variant='outlined' value={store.name} onChange={(e) => setStoreData({ ...store, name: e.target.value, }) } />Traté de imitar el comportamiento pero creo que tiene que ser más complejo. El problema es que quería tener 2 o 3 de estos "seleccionar entrada" para cada fruta. Y cada uno tendría múltiples opciones de int como 1, 2, 3. Y dependiendo del valor objetivo, inserte en la matriz de frutas esa cantidad de frutas. Esto es lo que tenía.
<Select value={store.fruits} label='Fruits' onChange={(e) => setStoreData({ ...store, fruits: e.target.value, }) }> <MenuItem value={1}>1</MenuItem> <MenuItem value={2}>2</MenuItem> <MenuItem value={3}>3</MenuItem> </Select>Entonces, idealmente, tendría 3 de estas entradas, una para cada fruta como plátanos y manzanas, y el número que el cliente eligió sería el número de entradas que el número plátano se insertaría en la matriz.
Ejemplo: Un select que dice tengo 3 (el número 3) plátanos. Y obtendría en la base de datos esto.
{ "name": store "fruits": ["banana", "banana", "banana"] }Estoy usando @mui/material para reaccionar.
Una buena solución podría ser cambiar la estructura de su estado a una más fácil de ingresar, luego transformar este valor a uno que coincida con el esquema de su tienda al momento del envío.
Su declaración de estado podría verse así;
const [store, setStoreData] = useState({ name: "", fruits: { apple: 0, banana: 0, orange: 0 }, });Luego puede tener un método compartido para actualizar el valor de las frutas en su estado.
const handleChangeFruit = (name, value) => { setStoreData(store => ({ ...store, fruits: { ...store.fruits, [name]: value } })); } Entonces su entrada de Select de frutas se convierte en:
<Select value={store.fruits.apple} label='apple' onChange={(e) => handleChangeFruit('apple', parseInt(e.target.value)) }> <MenuItem value={1}>1</MenuItem> <MenuItem value={2}>2</MenuItem> <MenuItem value={3}>3</MenuItem> </Select>Para transformar este estado en la forma de su esquema, puede hacer algo como a continuación;
const getStoreData = () => { const fruits = Object.entries(store.fruits).reduce( (acc, cur) => acc.concat(new Array(cur[1]).fill(cur[0])), [] ); return { name: store.name, fruits, }; }; Su método handleSubmit ahora se convierte en:
const handleSubmit = (e) => { e.preventDefault(); dispatch(addStore(getStoreData())); };Esto debería funcionar.
Para obtener puntos inteligentes adicionales, incluso puede generar los campos Select dinámicamente así:
Object.keys(store.fruits).map((fruit) => ( <Select key={fruit} value={store.fruits[fruit]} label={fruit} onChange={(e) => handleChangeFruit(fruit, parseInt(e.target.value))} > <MenuItem value={1}>1</MenuItem> <MenuItem value={2}>2</MenuItem> <MenuItem value={3}>3</MenuItem> </Select> ));