React / Redux: cambia efectivamente el estado correspondiente de un componente en el árbol de Redux

poroia

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 idde element2 de child1 y iden 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.

poroia

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 elements, decidí usar una combinación de fuerza bruta y la ruta de objeto predicha.

En este escenario particular, Parentes el nodo común entre todos los elements, por lo que una búsqueda de fuerza bruta idfuncionarí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 overwriteopciones 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 cloneDeepfunció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: 13comenzando 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

Editado en
0

Déjame decir algunas palabras

0Comentarios
Iniciar sesiónRevisión de participación posterior

Artículos relacionados

TOP Lista

CalienteEtiquetas

Archivo