Video Summary and Transcription
Esta charla se centra en la gestión efectiva del estado de React y las lecciones aprendidas durante los últimos 10 años. Los puntos clave incluyen la separación del estado relacionado, la utilización de UseReducer para proteger el estado y actualizar múltiples piezas de estado simultáneamente, evitar la sincronización de estado innecesaria con useEffect, el uso de abstracciones como React Query o SWR para la obtención de datos, la simplificación de la gestión del estado con hooks personalizados y el aprovechamiento de refs y bibliotecas de terceros para la gestión del estado. También se proporcionan recursos y servicios adicionales para un aprendizaje y soporte adicional.
1. Estado de React y lecciones aprendidas
Hola, vamos a hablar sobre el estado efectivo de React y 10 años de lecciones aprendidas. Toda esta charla va a ser sobre la gestión del estado. Comencemos con una de las cosas que veo más comúnmente en las revisiones de código, que es separar el estado relacionado. Otro lugar donde comúnmente podrías ver esto podría ser donde alguien elige crear un estado como para la información del usuario. La segunda que he aprendido es, ten cuidado cuando hacemos múltiples llamadas de uso del estado seguidas.
Hola, vamos a hablar sobre el estado efectivo de React y 10 años de lecciones aprendidas. Tengo la suerte de haber estado trabajando en React desde que se liberó hace unos 10 años, así que estas son algunas lecciones que he aprendido en el camino.
Toda esta charla va a ser sobre la gestión del estado. Tenemos unos 20 minutos para trabajar aquí.
Comencemos con una de las cosas que veo más comúnmente en las revisiones de código, que es separar el estado relacionado. Esta solución es bastante simple, que es unificar el estado relacionado. Ahora, cuando hablo de estado relacionado, el concepto aquí es pensar en el estado donde las propiedades se aplican entre sí, donde se relacionan entre sí. Una buena manera de pensar en esto es si salto por aquí por un momento, tengo una pequeña aplicación configurada que está usando Vite. Voy a acercar un poco aquí, asegurarme de que todos puedan leer la pantalla, y luego tengo la aplicación funcionando aquí a la izquierda para que podamos ver las palabras hola allí. Ahora, ¿qué pasaría si viniera y dijera, crear algún estado, y quisiera crear algún estado como mi dirección y establecer dirección, y mi ciudad y establecer ciudad, y mi país, y así sucesivamente, así que puedes empezar a ver cómo he creado este estado separado para la dirección, para la ciudad, para el país. Y esto es a lo que me refiero con estado relacionado. Estos están relacionados porque presumiblemente cuando realmente voy a guardar este estado en el servidor, lo que voy a hacer es enviar una llamada HTTP para enviar mi dirección, y mi dirección está compuesta de mi dirección de calle, y mi ciudad, y mi país, y así sucesivamente. Así que lo útil aquí es en lugar de tener tres piezas de estado, es tener solo una pieza de estado, que podría llamarse mi dirección, y establecer dirección, y luego esto sería un objeto que contendría cosas como mi ciudad, estado, país, dirección de calle, y así sucesivamente. Así que unificar ese estado relacionado tiene un par de beneficios. Un beneficio es, observa que tengo una llamada de uso de estado aquí en lugar de dos, tres, cuatro, cinco, seis. Podría ser un número alto. Lo otro es, cuando voy a inicializar esto, es más simple porque piensa en lo que podría pasar. Imagina que esto es un formulario que se va a llenar con datos del servidor. Así que voy a buscar algunos datos a través de HTTP, y luego voy a poner esos datos en el estado. Bueno, si voy a hacer eso, es más fácil tomar el objeto que recibo del servidor y ponerlo en una pieza de estado que dividirlo en piezas separadas de estado. La otra razón por la que esto es útil es, cuando voy a enviar esto de vuelta al servidor, presumiblemente, voy a querer enviar un objeto al servidor, no un montón de solicitudes HTTP separadas. Así que cuando voy a enviar esto de vuelta, también es más simple. Disculpe. Bueno, esa es la primera lección, simplemente agrupando el estado relacionado.
Otro lugar donde comúnmente verás esto podría ser donde alguien elige crear estado como para la información del usuario, y podría tener nombre y apellido y todas estas otras piezas de datos que se relacionan con el usuario, tal vez su edad y sus mascotas, quién sabe, cualquier información que estemos recopilando, donde suceda que la recopilamos. De nuevo, agrupa esto en un objeto de usuario, tenemos una pieza de estado, es más fácil de hidratar y más fácil de enviar. Así que esa es la primera lección que he aprendido.
La segunda que he aprendido es, ten cuidado cuando hacemos múltiples llamadas de uso del estado seguidas. Y cuando vemos este tipo de cosas, a menudo es una señal de que deberíamos unificar esas llamadas de establecimiento de estado juntas unificando el estado, muy parecido a lo que acabo de mostrar antes, o también podría ser una señal de que deberíamos considerar el uso de UseReducer. Ahora, diré, recientemente hice una encuesta en Twitter y me sorprendió porque alrededor de la mitad de los desarrolladores de React nunca han usado UseReducer, y esto fueron miles de personas que respondieron a mi encuesta, y luego hay una cantidad justa que dice que prácticamente nunca lo usan.
2. Beneficios de UseReducer
UseReducer es una herramienta subutilizada que protege nuestro estado y evita múltiples llamadas de set state. Es preferible a UseState en términos de protección del estado y actualización de múltiples piezas de estado simultáneamente.
Entonces, UseReducer es una herramienta subutilizada, y realmente es un maravilloso hook que creo que la gente a menudo olvida, por lo que te animaría a pensar en usarlo más. Y cuando hablo de unificar, si vuelvo aquí, voy a hacer clic en unificar para que puedas ver a qué me refiero aquí. Entonces, estas piezas de estado, esto no es tan poderoso como UseReducer. No puedo probarlo de forma aislada. No puedo validar ese data antes de establecerlo. Por lo tanto, probablemente sea preferible seguir adelante y usar UseReducer en su lugar, pero esto es a lo que me refería. Cuando hablamos de UseReducer, una de las cosas que hace realmente bien es proteger nuestro estado. Así que descubrí que puede ser bastante útil. Así que podemos mirar aquí. Podría comprobar y decir, está bien, en realidad no voy a establecer este estado porque quiero hacer algún tipo de lógica aquí solo para asegurarme de que la carga útil que he recibido es lo que esperamos. Y esto es una de las cosas poderosas acerca de UseState o lo siento, acerca de UseReducer es que protege nuestro estado. Piensa en UseState, no se protege a sí mismo. Podemos llamar al setter cuando queramos. Así que eso es un beneficio que es único para UseReducer. Y también con UseReducer, puedo terminar evitando hacer múltiples llamadas de set state. Así que aquí notarás que estoy llamando a SetUser y estoy llamando a SetIsLoading. Bueno, en su lugar, podría simplemente hacer un dispatch y decir SaveUser y luego, detrás de escena, la llamada de UseReducer, el reducer dentro de ella, puede actualizar una o más piezas de estado al mismo tiempo. Así que lo que busco es en las revisiones de código, cuando veo que se llama a setstate varias veces seguidas, me hace pensar que tal vez debería unificar ese estado si está relacionado o tal vez deberíamos considerar UseReducer en su lugar. Ese fue el punto dos.
3. Sincronización de Estado y useEffect
La sincronización de estado y useEffect a menudo es una señal de estado innecesario. En su lugar, intenta derivar el estado utilizando herramientas subutilizadas como deriveState. Evita usar useEffect para actualizar otro estado cuando ocurre un cambio de estado. Presta atención a si puedes derivar los valores que necesitas del estado existente. Por ejemplo, puedes calcular los errores de validación en un formulario en función de los valores del formulario y los campos requeridos. El consejo número cuatro es sobre la obtención de datos y useEffect.
Muy bien, volvamos aquí y miremos el siguiente. Otra cosa que a menudo veo es la sincronización de estado y useEffect. Y con eso, quiero decir, a veces veremos a alguien usar useEffect para decir, acaba de ocurrir este cambio de estado en mi componente. Y luego, cuando ocurre ese cambio de estado, quiero venir aquí y ejecutar alguna lógica y luego actualizar otro estado. El problema con eso es que es innecesario. En realidad es una señal de estado innecesario en general porque lo que normalmente puedes hacer en su lugar es deriveState. Y deriveState es una herramienta subutilizada como desarrollador de React.
Y puedo mostrarte un ejemplo muy forzado si volvemos aquí al código de nuevo. Imagina, por ejemplo, que tengo un estado simple aquí. Bueno, de hecho, lo tengo a mano aquí. Así que tengo firstName y lastName, y voy a hacer algo tonto aquí. Podría venir aquí y decir, está bien, voy a usar useEffect. Y voy a usar useEffect para hacer algo como esto. Tengo const fullName aquí, y voy a tener un setter para fullName aquí, y simplemente lo estableceré en una cadena vacía inicialmente aquí. Pero luego en este useEffect, podría querer decir que quiero establecer fullName en firstName y lastName, y querría ejecutar esto cada vez que cambien firstName o lastName. Ahora, mirarás esto y pensarás, bueno, esto es tonto. Yo no haría esto. Reconozco que podría obtener fullName simplemente tomando firstName o lastName y uniéndolos. Pero en realidad, podemos cometer fácilmente este error cuando terminamos con más estado y no nos damos cuenta de que podríamos derivar valores de ese estado existente. Así que lo que te animo a hacer es prestar mucha atención a si podrías derivar los valores que necesitas del estado existente.
Ahora, en este caso, la solución no es usar useEffect, y la solución no es ni siquiera declarar una pieza separada de estado. Es simplemente tener un valor que derive los dos. Así que podría decir const, fullName es igual a firstName más lastName, así, o podría usar una cadena de plantilla. Ahora, de nuevo, esto parece tonto, esto parece obvio, pero lo señalo porque es un error fácil de cometer cuando las cosas se vuelven más complejas. Un lugar donde uso esto es, a menudo verás a la gente declarar una pieza de estado para mantener los errores de un formulario, para mantener ese estado de validation, para decir, está bien, aquí están los errores en el formulario. No necesariamente necesitas ese estado porque si piensas en cómo funcionan los errores en un formulario cuando se está validando, esos errores pueden derivarse de los valores en el formulario. Así que una vez que conozco los valores y una vez que sé qué campos son obligatorios, en realidad puedo calcular qué errores de validation están ocurriendo en cada renderizado y luego decidir si mostrarlos en función del estado del formulario en sí. Muy bien, ese es el consejo número tres.
Pasemos aquí al consejo número cuatro. Este es muy común, la obtención de datos y useEffect.
4. Obtención de Datos y Uso de useEffect
Hemos estado obteniendo y usando useEffect durante mucho tiempo, pero es hora de comenzar a usar abstracciones como React Query o SWR. Estas herramientas proporcionan estado de carga, manejo de errores, almacenamiento de datos, caché, y más. También resultan en menos código. En lugar de usar useEffect, intenta derivar el estado y usar la URL como una única fuente de verdad.
Hemos estado obteniendo y usando useEffect desde que, bueno, los hooks salieron hace mucho tiempo y antes de eso lo estábamos haciendo en component-did-mount. Y considero esto un error. Sé que esa es una palabra fuerte, pero la razón por la que lo considero un error es como desarrolladores de React, probablemente deberíamos estar usando abstracciones ahora y hay muchas buenas abstracciones. Y para enfatizar, esas abstracciones todavía están usando useEffect de React, pero esas abstracciones nos dan un conjunto de bondades que no obtenemos en useEffect.
Lo complicado de useEffect es que es muy fácil equivocarse y es fácil olvidar una serie de cosas que son realmente importantes. Y cuando digo eso, esto se enfatiza cuando miras herramientas como React Query, por ejemplo, que es una de mis formas favoritas de manejar este problema. Piensa en lo que nos da React Query. Nos está dando estado de carga, manejo de errores, datos para almacenar el actual, o debería decir estado para almacenar los datos que recuperamos. Y luego va a hacer cosas como volver a buscar cuando mi conexión regresa, también me va a dar la capacidad de almacenar en caché los registros para que cuando me muevo por la aplicación, veo instantáneamente los datos que se han obtenido previamente. También puedo borrar esa caché usando claves. Va a volver a buscar cuando voy a una pestaña, la lista continúa. Muchas cosas que son fáciles de olvidar. Entonces, herramientas como React Query o SWR son realmente atractivas.
Ahora, también quiero enfatizar que el otro beneficio que obtienes aquí es simplemente mucho menos código. Así que voy a salir de esto por un segundo. Y lo que quiero mostrar es, bueno, voy a mostrar este tweet rápidamente ya que lo tengo en la pantalla. Si useEffect es la respuesta, puede que esté haciendo la pregunta equivocada. Entonces, si pregunto, ¿cómo sincronizo el estado? La respuesta es no, intenta derivarlo tal como mostré en el ejemplo anterior. Si la pregunta es, ¿cómo obtengo y juego en React? Bueno, sugiero que no intentes usar una biblioteca que haga el useEffect detrás de escena por ti. Y si la pregunta es, ¿cómo copio los valores de la URL en el estado? No, usa la URL como tu única fuente de verdad. Así que esos son algunos ejemplos donde alguien podría recurrir a useEffect innecesariamente.
Bueno, entonces vayamos aquí al navegador por un segundo. Y si entro aquí y bueno, en realidad, no puedo mostrarlo de esa manera, no quiere, simplemente voy a arrastrar este navegador en su lugar. Bueno, entonces voy a ir a Twitter porque tengo un tweet fijado que quiero mostrar aquí. Y este tweet fijado son 10 lecciones que he aprendido sobre el manejo del estado en React. Así que podrías encontrar esto útil porque es definitivamente relevante para lo que estamos hablando aquí en esta masterclass. Pero quería mostrar esta imagen en particular. Y esta imagen ayuda a enfatizar por qué digo que usar useEffect para obtener datos es realmente algo que debería estar en el pasado. Lo que queremos usar es algún tipo de abstracción que tome nuestro código y lo colapse. Como miras el antes allí.
5. Gestión del Estado de React y Manejo del Estado en la URL
Observa todo el código que está en este inicio. Nota que tuvimos que asegurarnos de poner un finally para que estableciéramos correctamente loading en false. Tuvimos que tener un catch para que pudiéramos tener un error y luego decidir qué hacer con él. Tuvimos que declarar tres piezas diferentes de estado. Y luego tenemos que tener lógica aquí abajo para manejar todo esto. Así que todo este código se colapsa si usas un hook personalizado.
Observa todo el código que está en este inicio. Nota que tuvimos que asegurarnos de poner un finally para que estableciéramos correctamente loading en false. Tuvimos que tener un catch para que pudiéramos tener un error y luego decidir qué hacer con él. Tuvimos que declarar tres piezas diferentes de estado. Y luego tenemos que tener lógica aquí abajo para manejar todo esto. Así que todo este código se colapsa si usas un hook personalizado.
Ahora, de hecho, tengo un curso llamado Gestión del Estado de React en Pluralsight. Lo actualicé hace un par de días. Así que la fecha de publicación es fresca a partir de 2023. Y de hecho, muestro cómo construir este hook useFetch. Lo muestro solo para que puedas entender cómo crear el tuyo propio pero en realidad no recomiendo usarlo. Lo muestro como una herramienta de enseñanza para que puedas ver cómo usar herramientas como React Query y por qué son tan útiles. Así que este es solo un ejemplo. Pero si usara React Query, mi API aquí se vería muy similar a este hook useFetch personalizado que acabo de mostrar.
Bueno. Así que solo tenemos 20 minutos. Así que quería asegurarme de que, en estos 20 minutos mostré esta diapositiva en particular. Esta es la forma en que pienso sobre el Estado de React. Y si tuviera que resumir la oportunidad central para cualquier desarrollador de React aquí es, asegúrate de mantener estas ocho formas de manejar el Estado de React en tu cabeza. Uno de los errores más comunes que veo es olvidar la URL. A menudo estamos declarando estado a través de useState o useReducer que en realidad pertenece a la URL. Y una buena señal de eso es, pregúntate a ti mismo, si comparto la URL con alguien más, ¿verán las mismas cosas que estoy viendo ahora? Y si la respuesta es no, esa es una señal de que podríamos querer ponerlo en la URL. Algunos lugares donde cometemos este error es, cuando olvidamos mirar cosas como, ¿está abierto este acordeón? ¿Está seleccionada esta pestaña? ¿Dónde estoy desplazado en la página? ¿Qué encabezado estoy más cerca? Esas son las cosas que son realmente agradables de poner en la URL. Otro ejemplo es ¿en qué página estoy? ¿O qué búsqueda o qué filtros he ejecutado? Todos ellos son maravillosos en la URL, para que pueda marcarla y compartirla. Algunos de estos otros pasaré rápidamente, el almacenamiento web no está realmente vinculado a React, pero sí, considera el almacenamiento local o IndexedDB, ese tipo de herramientas. El estado local es el predeterminado que recomiendo. Declara un estado usado, ponlo en un componente. Si necesitas compartirlo con unos pocos, entonces levanta el estado, corta y pega, ponlo en el padre. Tanto como puedas, intenta derivar el estado del estado existente. Y a veces tal vez ni siquiera quieras renderizar ese estado.
6. Uso de Refs y Bibliotecas de Terceros
Puedes usar refs para retener valores, incluyendo para la funcionalidad de deshacer. Los refs son útiles para administrar el estado que no quieres renderizar. Considera usar el contexto para el estado global o funciones. Las bibliotecas de terceros como React Query, SWR y RTK Query son excelentes para manejar tipos específicos de estado, como el estado global o remoto. Consulta mi tweet fijado en twitter.com/housecore para los puntos clave de esta charla y mi enlace al curso de gestión del estado de React en Pluralsight. Contáctame en reactjsconsulting.com para formación, consultoría, revisiones de código y planificación arquitectónica. Sígueme en Twitter para tweets diarios sobre desarrollo front-end en JavaScript. Encuentra mis cursos en Pluralsight.com.
Solo quieres retener el valor. Podrías querer usar un ref. Los refs también pueden retener el estado. Ten en cuenta que los refs también son útiles para cosas como deshacer. Por lo tanto, es algo que quieres mantener en segundo plano. Es cualquier variable que no quiero renderizar.
Los refs son una herramienta. Considera el contexto si tengo un estado global o funciones globales. Y finalmente, las bibliotecas de terceros son maravillosas para tipos específicos de estado como el estado global o el estado remoto. Cuando digo estado remoto, me refiero al estado obtenido de un servidor utilizando herramientas como React Query, SWR, RTK Query, y así sucesivamente.
Bueno, ya casi nos quedamos sin tiempo, pero quiero llamar tu atención sobre, si vas a twitter.com slash housecore. Tengo este tweet fijado que tiene algunos de los puntos clave que he hecho en esta charla y otros que no tuve tiempo de hacer. En la parte inferior de este tweet, también verás que tengo un enlace a mi último curso, que es la gestión del estado de React en Pluralsight. Hay una prueba gratuita disponible. También compartiré estas diapositivas para que puedas llegar al resto de ellas. Porque de nuevo, en 20 minutos, no tengo tiempo para repasar todos los tips que tengo para el estado, pero quería que los tuvieras. Así que los he puesto aquí. Hay alrededor de 19 aquí, así que no puedo cubrir 19 en 20 minutos. Así que si quieres contactarme, mi empresa es reactjsconsulting.com. Viajo por el mundo y formo equipos y consulto a empresas. Hago revisiones de código, planificación arquitectónica. Mi negocio es ayudar a los desarrolladores de React a ser más efectivos. Así que he tenido la oportunidad de hacer eso en todo el mundo. Además, si quieres seguirme en Twitter, twitteo una vez al día sobre diferentes temas, pero a menudo sobre desarrollo front-end en JavaScript. Puedes encontrar mis cursos en Pluralsight.com. Gracias por ver la masterclass.
Comments