Así que básicamente tienen una jerarquía similar entre mis componentes y estado Redux, representada a continuación, donde cada componente tiene una id
, name
, details
, etc:
Redux hierarchy:
parent -> child1 -> element1
element2
element3
child2 -> element1
element2
React hierarchy:
ParentComponent -> ChildComponent -> ElementComponent
Supongamos que quisiera que element2 de child1 cambiara su nombre, reflejándolo en el estado de Redux, ¿cómo haría esto de manera eficiente?
Lo que quiero es crear de alguna manera un enlace usando el id
de element2 de child1 y id
en el estado para poder cambiar el estado correspondiente de Redux sin hacer una búsqueda profunda dentro de la tienda Redux para cambiar el estado correspondiente.
Podría crear esto de manera efectiva usando el modelo de estado de React y hacer que cada componente administre su propio estado, pero como necesito este estado en otro lugar, ¿cómo abordaría esto en el estado de Redux? Gracias por adelantado.
Normalmente, podría simplemente seguir una ruta de objeto predicha, pero debido a que la ruta de objeto puede ser variable debido a la naturaleza de element
s, decidí usar una combinación de fuerza bruta y la ruta de objeto predicha.
En este escenario particular, Parent
es el nodo común entre todos los element
s, por lo que una búsqueda de fuerza bruta id
funcionaría bastante bien.
Esta función reutilizable proporcionaría una búsqueda recursiva de fuerza bruta en el nodo raíz para cada objeto y proporcionaría una devolución de llamada para realizar en cada objeto.
export const iterateNodes = (obj, callback) => {
if (!obj) return undefined
for (let property in obj) {
if (obj.hasOwnProperty(property) && obj[property] != null) {
if (obj[property].constructor === Object) {
iterateNodes(obj[property], callback)
callback(obj[property])
} else if (obj[property].constructor === Array) {
for (let i = 0; i < obj[property].length; i++) {
iterateNodes(obj[property][i], callback)
callback(obj[property][i])
}
} else {
// console.log(obj[property])
}
}
}
return obj
}
Esto se extrajo de otra pregunta de StackOverflow y se modificó un poco. Parece que no puedo encontrar la fuente.
Luego puede crear otra función para modificar el nodo con opciones particulares. Este fragmento tiene overwrite
opciones en caso de que sea necesario sobrescribir todo el objeto.
export const modifyNodeById = (
root,
id,
modification,
options = {}
) => {
if (!id) throw new Error('id not specified')
return iterateNodes(root, node => {
if (node.id === id) {
if (options.overwrite)
Object.getOwnPropertyNames(node).forEach(key => delete node[key])
Object.assign(node, { ...modification })
}
})
}
Importar nota: esta función muta el objeto.
La mutación de estado debe evitarse al 100%, por lo que la salida fácil para esta es simplemente usar la cloneDeep
función de lodash para crear una copia profunda. Probablemente podría optimizar para copiar solo las ramas necesarias en el estado, pero a menos que su estado sea espeso, probablemente no valga la pena.
Entonces, una respuesta final podría ser:
modifyNodeById(parent, 13, { isUnlocked: true })
Para agregar las propiedades al nodo del objeto id: 13
comenzando la búsqueda debajo parent
.
Este artículo se recopila de Internet, indique la fuente cuando se vuelva a imprimir.
En caso de infracción, por favor [email protected] Eliminar
Déjame decir algunas palabras