¿Es posible establecer claves dinámicamente cuando se usa esta sintaxis como se muestra en este ejemplo?
En este ejemplo, la función changeValue cambia el objeto de estado que se muestra en la parte superior. La función changeValue toma una matriz de claves de cadena para usar como una forma de establecer dinámicamente el valor.
Este código no funciona y no estoy buscando enfoques alternativos: (dentro de una alternancia razonable)
const state = { profile: { isFollowing: false, }, person: { characteristics: { gender: "male" } } } console.log(state.profile.isFollowing) //false console.log(state.person.characteristics.gender) //male function changeValue(keys, value){ state[keys] = value } console.log(state.profile.isFollowing) //true console.log(state.person.characteristics.gender) //female changeValue(["profile", "isFollowing"], true) //<-- using an array of strings //AFTER STATE CHANGE //const state = { // profile: { // isFollowing: true, // }, // person: { // characteristics: { // gender: "male" // } // } //} changeValue(["person", "characteristics", "gender"], "female") //<-- using an array of strings //AFTER STATE CHANGE //const state = { // profile: { // isFollowing: true, // }, // person: { // characteristics: { // gender: "female" // } // } //} No quiero tener que definir manualmente las [keys] dentro de la función changeValue .
es posible?
Cosa segura. Una función auxiliar como esta debería funcionar.
const state = { profile: { isFollowing: false, }, person: { characteristics: { gender: "male" } } } function changeValue(target, path, value) { for(let i = 0; i < path.length - 1; i++) { target = target[path[i]]; } target[path[path.length - 1]] = value; } console.log(JSON.stringify(state)); changeValue(state, ["profile", "isFollowing"], true); console.log(JSON.stringify(state)); changeValue(state, ["person", "characteristics", "gender"], "female"); console.log(JSON.stringify(state));No, no puede simplemente indexar un objeto con una matriz y hacer que descienda automáticamente jerárquicamente. Hay módulos que puede instalar que le permiten hacer cosas similares; por ejemplo, consulte el método set de lodash . Tienes que unir la matriz en un solo archivo . cadena de ruta de clave separada, pero es básicamente lo que está buscando.
Sin embargo, también es bastante fácil hacerlo usted mismo en Vanilla JS con un bucle:
function changeValue(keyPath, newValue) { let target = state let key = keyPath[0] for (let i=1; i<keyPath.length; ++i) { target = target[key] key = keyPath[i] } target[key] = newValue; }Aquí está en acción:
const state = { profile: { isFollowing: false, }, person: { characteristics: { gender: "male" } } } function changeValue(keyPath, newValue) { let target = state let key = keyPath[0] for (let i=1; i<keyPath.length; ++i) { target = target[key] key = keyPath[i] } target[key] = newValue; } changeValue(["profile", "isFollowing"], true); changeValue(["person", "characteristics", "gender"], "female") console.log(state);Otro método podría ser usar reduce para trabajar el objeto hasta llegar al último elemento y luego establecer su valor.
const state = { profile: { isFollowing: false, }, person: { characteristics: { gender: "male" } } } function changeValue(keys, value){ keys.slice(0,-1).reduce((acc, k) => acc[k], state)[keys.slice(-1)] = value } changeValue(["profile", "isFollowing"], true); console.log(state); changeValue(["person", "characteristics", "gender"], "female"); console.log(state);