En un proyecto de React que usa la biblioteca antd, creé una lista de opciones a partir de datos json que se completan como una lista desplegable. El siguiente es el código de referencia
los datos json
const newData = [ { id: 123, name: "Vijay" }, { id: 345, name: "Sanket" }, { id: 546, name: "Hitesh" }, { id: 789, name: "Sameer" }, { id: 421, name: "Akshay" } ]; Esos datos se usan aquí en <Select/>
<h2>Data 1</h2> <Select onChange={(key, val) => handleOnValuesChange(key, val)} placeholder="Select any one" style={{ width: 120 }} options={newData.map((_) => ({ label: _.name, value: _.id }))} bordered={false} /> <br /> <h2>Data 2</h2> <Select onChange={(key, val) => handleOnValuesChange(key, val)} placeholder="Select any one" style={{ width: 120 }} options={newData.map((_) => ({ label: _.name, value: _.id }))} bordered={false} />La función onChange
const handleOnValuesChange = (key, val) => { const allData = newData.map((data) => { if (data.id === val) { return { ...data, disabled: true }; } else { return { ...data, disabled: false }; } }); console.log("NEW DATA", allData); };Cuando se selecciona Vijay y Akshay, espero los datos como
0: {id: 1, value: "Vijay", disabled: true } 1: {id: 2, value: "Sanket", disabled: false} 2: {id: 3, value: "Hitesh", disabled: false } 3: {id: 4, value: "Sameer", disabled: false } 4: {id: 5, value: "Akshay", disabled: true }pero obteniendo salida como
0: {id: 1, value: "Vijay", disabled: false } {/* This disabled should change to true */} 1: {id: 2, value: "Sanket", disabled: false} 2: {id: 3, value: "Hitesh", disabled: false } 3: {id: 4, value: "Sameer", disabled: false } 4: {id: 5, value: "Akshay", disabled: true }¿Cómo abordar esto? Cualquier solución apropiada muy apreciada
Este es el enlace de codesandbox como: https://codesandbox.io/s/bordered-less-antd-4-17-0-alpha-7-forked-wtur0
Los nuevos datos deben almacenarse en un estado para lograr la desactivación de las opciones ya seleccionadas. Esto se debe a que el DOM se vuelve a renderizar solo si se actualizan los accesorios o el estado.
Entonces, en su código, dado que los datos no se almacenan en ningún estado, no cambia la opción no enfocada, una vez que se cambia la opción enfocada.
Hice algunos cambios en el código y agregué el ejemplo de trabajo en sandbox .
const [data, setData] = React.useState(updatedData); //store the newData with disabled added const [prevKey, setPrevKey] = React.useState(null); //store the last changed option const handleOnValuesChange = (key, val) => { const updating = [...data]; setPrevKey(val.value); data.map((d, i) => { if (d.id === val.value) { updating[i] = { ...d, disabled: true }; } if (d.id === prevKey) { //this toggles the previous selected value to false updating[i] = { ...d, disabled: false }; } }); setData(updating); }; ..... <Select onChange={(key, val) => handleOnValuesChange(key, val)} placeholder="Select any one" style={{ width: 120 }} options={data .filter((d) => d.disabled === false) //this shows only the options that are not disabled .map((_) => { console.log(_.name) console.log(_.id) return({ label: _.name, value: _.id })})}siempre está utilizando el elemento base newData. por lo tanto, en cada llamada de handleOnValuesChange no tiene ningún valor establecido en deshabilitado.
necesita actualizar newData o usar alguna otra variable temporal.
también el valor es el primer parámetro para onChange utilizado por antd select.
let newData = [ { id: 123, name: "Vijay", disabled: false, }, { id: 345, name: "Sanket", disabled: false, }, { id: 546, name: "Hitesh", disabled: false, }, { id: 789, name: "Sameer", disabled: false, }, { id: 421, name: "Akshay", disabled: false, } ]; const handleOnValuesChange = (val) => { console.log("VAL", val); newData = newData.map((data) => { console.log(data, val); if (data.id === val) { return { ...data, disabled: true }; } return data; }); console.log("NEW DATA", newData); };Revisé el código de la zona de pruebas y encontré varios problemas con su código.
newData con el valor de actualización; de lo contrario, se procesarán los datos antiguos.if (data.id === val.value) en lugar de if (data.id === val) en la función handleOnValuesChange.Puede verificar la implementación modificada en Sandbox
Será genial si usas el estado para newData