Teniendo esta siguiente estructura de datos:
const foo = [ { a: 'xxx', b: 'xxx', c: { e: 'xxx', ... } } ... ] ¿Es posible acceder al valor de e con este objeto de ruta?
const path = [0, 'c', 'e']y editarlo?
lo intenté haciendo
setResponseState(prevState => { let data = prevState.responseData path.forEach(id => data = data[id]) data = {} return prevState }) path es un valor de contexto, pero descubrí que los data eran una copia y, por lo tanto, no se guardaron en el estado de reacción
Gracias
Si modifica la actualización del último valor en forEach como se muestra a continuación, debería funcionar para editar el objeto. Básicamente, esto evita anular la referencia del objeto y solo actualiza el valor.
const foo = [ { a: "xxx", b: "xxx", c: { e: "xxx", }, }, ]; const path = [0, "c", "e"]; setResponseState((prevState) => { let data = prevState.responseData; path.forEach((id, i) => i === path.length - 1 ? (data[id] = {}) : (data = data[id]) ); return prevState; });Mira esta muestra mutando el objeto.
const foo = [ { a: "xxx", b: "xxx", c: { e: "xxx", }, }, ]; const path = [0, "c", "e"]; let data = foo; path.forEach((id, i) => i === path.length - 1 ? (data[id] = {}) : (data = data[id]) ); console.log(foo)Si solo desea acceder al valor, su código existente está mayormente bien, solo necesita devolver el valor.
const foo = [ { a: 'xxx', b: 'xxx', c: { e: 'xxx', } } ] const path = [0, 'c', 'e'] function setResponseState(prevState) { let data = foo; //prevState.responseData path.forEach(id => data = data[id]) return data; }; console.log(setResponseState());Esto (acceder a un valor anidado a través de una ruta proporcionada) es una tarea estándar para el método de reduce muy expresivo en colaboración con el encadenamiento opcional para garantizar una implementación a prueba de fallas...
const foo = [{ a: "zzz", b: "yyy", c: { e: "xxx", }, }]; console.log({ foo }); console.log( '[0, "c", "e"].reduce((value, key) => value?.[key], foo) ...', [0, "c", "e"].reduce((value, key) => value?.[key], foo) ); console.log( '[0, "C", "e"].reduce((value, key) => value?.[key], foo) ...', [0, "C", "e"].reduce((value, key) => value?.[key], foo) ); .as-console-wrapper { min-height: 100%!important; top: 0; }Si se trata de mutar la propiedad anidada de un objeto, preferiblemente se utilizaría el enfoque anterior dentro de una función...
const foo = [{ a: "zzz", b: "yyy", c: { e: "xxx", f: "uuu", }, }]; function assignValueToExistingNestedProperty(type, path, value) { const [lastKey, ...keyList] = path.reverse(); // access the next to last property value. const reference = keyList .reverse() .reduce((value, key) => value?.[key], type); Object.assign((reference ?? {}), { [lastKey]: value }); return type; } console.log({ foo }); console.log( 'assignValueToExistingNestedProperty(foo, [0, "c", "e"], "AAA") ...', assignValueToExistingNestedProperty(foo, [0, "c", "e"], "AAA") ); console.log( 'assignValueToExistingNestedProperty(foo, [0, "C", "e"], "BBB") ...', assignValueToExistingNestedProperty(foo, [0, "C", "e"], "BBB") ); console.log({ foo }); .as-console-wrapper { min-height: 100%!important; top: 0; }