¿Cuál es la forma óptima de transformar un mapa plano a una estructura de datos anidada utilizando React.js?
He estado reflexionando sobre la mejor manera de manejar la agrupación en mi aplicación. Es una aplicación de edición de video y estoy introduciendo la capacidad de agrupar capas. Si estás familiarizado con Figma u otros programas de diseño/edición de video, sabrás que generalmente existe la capacidad de agrupar capas.
Para mantenerlo simple en la aplicación, los datos de video son un mapa:
const map = {
"123": {
uid: "123",
top: 25,
type: "text"
},
"345": {
uid: "345",
top: 5,
type: "image"
},
"567": {
uid: "567",
top: 25,
type: "group",
children: ["345", "123"]
}
}
Luego, estoy agrupándolos dentro de una función de renderización (esto parece costoso):
const SomeComponent = () => {
const objects = useMemo(() => makeTrackObjects(map), [map]);
return (
<div>
{objects.map(object => {
return <div>Alguna capa que cambiará los datos causando re-renderizaciones</div>
})}
</div>
)
}
Aquí está la función que realiza la agrupación:
const makeTrackObjects = (map) => {
// convierte el mapa en un array
const objects = Object.keys(map).map((key) => ({ ...map[key] }));
// array plano de todos los objetos que se agruparán por su clave/id
const objectsInGroup = objects
.filter((object) => object.type === "group")
.map((object) => object.children)
.flat();
// filtrar los objetos que están anidados/agrupados
const filtered = objects.filter((object) => !objectsInGroup.includes(object.uid))
// insertar objetos como hijos durante la renderización
const grouped = filtered.map((object) => {
const children = object.children
? {
children: object.children
.map((o, i) => {
return {
...map[o]
};
})
.flat()
}
: {};
return {
...object,
...children
};
});
// los datos principales están planos pero ahora anidados para la interfaz de usuario. ¿Esto es ineficiente?
return grouped
}
Idealmente me gustaría mantener los datos planos, tengo mucho código que tendría que actualizar para profundizar en los datos. Es agradable tenerlos planos y utilizar transformadores solo cuando sea necesario.
La pregunta principal es si esto tiene sentido, si es eficiente, y si no lo es, ¿por qué?
davy.ai
No es muy eficiente manejar la agrupación dentro de la función de renderización, especialmente para un gran número de capas. Esto se debe a que la función
makeTrackObjects
se ejecuta cada vez que el componente se vuelve a renderizar, incluso si el objetomap
no ha cambiado.Una forma de optimizar esto sería mover la lógica de agrupación a una función independiente que se llame solo cuando cambia el objeto
map
. De esta manera, los datos agrupados se pueden almacenar en el estado y pasar aSomeComponent
como props. Esto evitaría renderizaciones innecesarias y mejoraría el rendimiento.También es posible mantener los datos planos y agregar una propiedad
groupId
a cada capa que indique a qué grupo pertenece. Esto simplificaría la lógica y la haría más eficiente, ya que la lógica de agrupación se puede manejar en la funciónmakeTrackObjects
durante la inicialización en lugar de en cada renderización.En general, la clave es evitar operaciones costosas dentro de la función de renderización y organizar los datos de una manera que tenga más sentido para las necesidades de su aplicación.