Tengo una variedad de objetos. Cada objeto se ve así:
{ "key": "pQSa6jgmsbFnQgJ1memDJ", "type": "div", "props": { "id": "pQSa6jgmsbFnQgJ1memDJ", "style": { "height": "100px", "backgroundColor": "#de4141" }, "className": "" }, "selected": true, "childNodes": [{ "key": "pQSa6jgmsbFnQgJ1memDJ", "type": "div", "props": { "id": "VrrQ1rMUOF6IOOKAZomor", "style": { "height": "100px", "backgroundColor": "#de4141" }, "className": "" }, "selected": false, "childNodes": [] }] } El problema es que cada objeto puede tener childNodes , y esos childs también pueden tener más childs... La propiedad que quiero cambiar está selected . Esta propiedad define si el objeto está seleccionado o no y, por lo tanto, muestra un nombre de clase diferente en el DOM. Tengo una función para anular la selección de todo (cambiar todas las propiedades seleccionadas del objeto a falso) que se ve así, donde content es un React state de reacción, la matriz que contiene estos objetos:
function () { const $ = _.cloneDeep(content); const z = $.map((c) => { let y = c; if (y?.childNodes && y.childNodes.length > 0) { y.childNodes = y.childNodes.map((h) => { let x = h; x.selected = false; return x; }); } y.selected = false; return y; }); setContent(z); setActive(null); } Pero esto solo cambiará los primeros childNodes. ¿Qué pasa si estos childNodes también tienen más childNodes? Necesitaría hacer un mapa, nuevamente, para esos childNodes manualmente. ¿Hay alguna manera de hacer esto (por ejemplo, usando lodash , que ya estoy usando para cloneDeep() )?
Podría utilizar un enfoque recursivo para establecer los valores de propiedad requeridos. Crearíamos una función como 'setPropertyDeep', pasaríamos el valor de propiedad requerido.
Esto actualizará el árbol de objetos a cualquier profundidad.
const input = { "key": "pQSa6jgmsbFnQgJ1memDJ", "type": "div", "props": { "id": "pQSa6jgmsbFnQgJ1memDJ", "style": { "height": "100px", "backgroundColor": "#de4141" }, "className": "" }, "selected": true, "childNodes": [{ "key": "pQSa6jgmsbFnQgJ1memDJ", "type": "div", "props": { "id": "VrrQ1rMUOF6IOOKAZomor", "style": { "height": "100px", "backgroundColor": "#de4141" }, "className": "" }, "selected": false, "childNodes": [] }] } function updatePropertyDeep(obj, property, value) { for(let k in obj) { if (k === property) { obj[property] = value; } else if (obj[k] && typeof(obj[k]) === 'object') { updatePropertyDeep(obj[k], property, value); } } return obj; } console.log('Setting true:', updatePropertyDeep(input, 'selected', true)) console.log('Setting false:', updatePropertyDeep(input, 'selected', false)) .as-console-wrapper { max-height: 100% !important; }usar recursividad
function updateChild(child){ if (!child || !Array.isArray(child)) { return } return child.map(el => { return { ...el, selected: false, childNodes: updateChild(el.childNodes) } }) } function main() { return updateChild(content); //setContent(z); //setActive(null); } const content = [ { "key": "pQSa6jgmsbFnQgJ1memDJ", "type": "div", "props": { "id": "pQSa6jgmsbFnQgJ1memDJ", "style": { "height": "100px", "backgroundColor": "#de4141" }, "className": "" }, "selected": true, "childNodes": [{ "key": "pQSa6jgmsbFnQgJ1memDJ", "type": "div", "props": { "id": "VrrQ1rMUOF6IOOKAZomor", "style": { "height": "100px", "backgroundColor": "#de4141" }, "className": "" }, "selected": false, "childNodes": [] }] } ] document.getElementById('result').innerHTML = JSON.stringify(main(), null, 2) <pre id="result"></pre>