es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿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é?

Tags:  , , , ,

Answer

  1. Avatar for 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 objeto map 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 a SomeComponent 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ón makeTrackObjects 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.

Comments are closed.