Dado el objeto de estado a continuación
{ colour: ['red', 'blue', 'green'], size: ['small', 'medium', 'large'], position: ['bottom', 'top', 'left', 'right'], } Necesito poder cambiar/actualizar sus valores de atributo attrValues así como las claves de atributo attrKey
Estoy usando la siguiente lógica para hacerlo:
setAttributes((prevState) => { const key = Object.keys(attributeToUpdate)[0]; if (key !== attrKey) { delete prevState[key]; } return { ...prevState, [attrKey]: attrValue }; }); Si cambio la clave de atributo de colour a color , funciona, pero el estado resultante cambia a:
{ size: ['small', 'medium', 'large'], position: ['bottom', 'top', 'left', 'right'], color: ['red', 'blue', 'green'], } Moviendo el atributo de color al final, me gustaría mantenerlo en su posición original.
Cualquier ayuda o sugerencia será muy apreciada.
Aunque se deben tener en cuenta las preocupaciones expresadas sobre el orden de inserción/precedencia de la clave, la solución que está buscando el OP podría acercarse a algo como el siguiente código proporcionado...
function renamePropertyAndKeepKeyPrecedence(obj, [oldKey, newKey]) { const descriptors = Object.getOwnPropertyDescriptors(obj); if (descriptors.hasOwnProperty(oldKey)) { Object .entries(descriptors) .reduce((target, [key, descriptor]) => { // delete every property. Reflect.deleteProperty(target, key); if (key === oldKey) { // rename addressed key. key = newKey; } // reassign every property. Reflect.defineProperty(target, key, descriptor) return target; }, obj); } return obj; } const sample = { position: ['bottom', 'top', 'left', 'right'], colour: ['red', 'blue', 'green'], size: ['small', 'medium', 'large'], }; console.log('before property renaming ...', { sample }); renamePropertyAndKeepKeyPrecedence(sample, ['colour', 'color']); console.log('after property renaming ...', { sample }); .as-console-wrapper { min-height: 100%!important; top: 0; }No puede controlar el orden de las teclas en un objeto; si el orden es importante, debe tener una matriz de objetos. Luego puede reconstruir el estado eliminando el elemento que desea y reemplazándolo.
La siguiente demostración muestra esto en la práctica:
let prevState = [ {key:"colour",values: ['red', 'blue', 'green']}, {key:"size", values:['small', 'medium', 'large']}, {key:"position",values:['bottom', 'top', 'left', 'right']} ] const indexToRemove = prevState.findIndex(x => x.key == "colour"); prevState = [ ...prevState.slice(0,indexToRemove), {key:"color", values:['red', 'blue', 'green']}, ...prevState.slice(indexToRemove+1) ] console.log(prevState)Entonces, si entiendo tu código, la corrección sería
setAttributes((prevState) => { const key = Object.keys(attributeToUpdate)[0]; const indexToRemove = prevState.findIndex(x => x.key == key); return [ ...prevState.slice(0,indexToRemove), {key:attrKey, values:attrValue}, ...prevState.slice(indexToRemove+1) ] });Y tendría que actualizar el resto de su código para usar una matriz de estado en lugar de un objeto.