Tenemos un componente de tabla de reacción donde necesitamos que las selecciones funcionen en diferentes páginas. Entonces tengo un Mapa para almacenar esas filas seleccionadas en las páginas. Pero para manipular las selecciones, tengo una clase llamada Selecciones
class Selections { eventMap = new Map(); addSelections(event) { .... return this; } }En el estado de reacción, creo una instancia de este objeto y actualizo el estado cuando se agregan o eliminan eventos.
// constructor this.state = { selections: new Selections() } function onToggle(e, data) { const { prevSel } = this.state; this.setState({ selections: prevSel.toggle(data) }) }Esto está funcionando como se esperaba. Sin embargo, otro miembro del equipo sugirió que es un olor a código y que no deberíamos usar objetos de clase personalizados en las selecciones porque también encapsula los métodos. No estoy seguro de entender completamente por qué una instancia de una clase personalizada con métodos es algo malo. Para mí, la capacidad de reutilizar las selecciones en varios componentes de la tabla en todo el producto y la unidad de prueba por separado supera la preocupación de tener métodos en el estado de reacción. ¿Hay algún problema con esta implementación que me esté perdiendo? ¿No es esto ampliamente utilizado en la industria?
Los objetos complejos, como un mapa o un conjunto, no activarán actualizaciones de estado a medida que los cambie, de la misma manera que tampoco lo haría un objeto en estado. Esto se debe a que los oyentes (useEffect, useMemo, lo que sea) que enumeran esas variables de estado en su lista de dependencias o accesorios de componentes siempre verán el mismo objeto. Con un objeto estándar, puede poner una clave de objeto específica como referencia en su lista de dependencias, siempre que el valor de esa clave sea una variable simple.
Para que sus cambios de estado se activen en la cadena, cada 'oyente' para ese cambio de estado necesitaría un nuevo valor para la variable. Por lo tanto, si está almacenando selections en estado, y selections es una instancia de Selections , entonces cada actualización de estado requerirá una nueva instancia de Selections para que esas actualizaciones se activen en la cadena. Si solo realiza un cambio en una instancia de Selections existente (incluso en el estado) y lo aplica al estado, sigue siendo la misma referencia de objeto, lo que no desencadenaría actualizaciones en la cadena. Verá lo mismo con cualquier objeto complejo (Objeto, Matriz, etc.).
Por cierto, hago algo muy similar, almacenando selecciones en un Conjunto (solo almaceno la clave principal de un objeto) en el estado. Cuando necesito actualizar el estado, es algo como esto
const addNewItem = (id) => setSelections((prev) => { const updated = new Set(prev); updated.add(id); return updated; }); Eso crea una nueva instancia de Set de la anterior, por lo que todas las actualizaciones activan el árbol de estado. Puedes hacer lo mismo con Map .