El objetivo de este tutorial no es hacer una aplicación de React e incluir Redux desde cero sino complementar los conocimientos adquiridos en el Curso de Redux por Bedu . Recomiendo entonces tomar este curso antes de continuar leyendo, de todos modos si no lo viste y ya tienes conocimientos sobre Redux puedes seguir aquí y aprender algo nuevo. Principalmente lo que haremos será convertir nuestros componentes de clase en funciones de React utilizando Hooks.
<h4>Introducción</h4>Es importante en el mundo laboral que convivimos día a día aprender y mejorar nuestras habilidades como desarrolladores de software, para lograrlo debemos tener frescos los conceptos básicos de cada herramienta con la que trabajamos. Redux a pesar de ser ya viejo para la velocidad en la que avanza la tecnología sigue siendo un pilar importante para construir aplicaciones web. Por otro lado, React Hooks es relativamente nuevo pero igual o quizás más importante que Redux a la hora de consolidar nuestros conocimientos como desarrolladores frontend expertos en React.
<h4>Redux</h4>Es simplemente una librería para manejar el estado de una aplicación construida con javascript por lo cual se puede usar independientemente a la librería o framework elegidos para crear dicha aplicación. Con respecto al estado, este refleja y pone condiciones sobre cómo se ven los elementos de la aplicación.
Los principios fundamentales de Redux son:
1 - Debe existir solo un store que almacene todo el estado (única fuente de la verdad).
2 - El store es de solo lectura, solo se puede cambiar emitiendo una action, un objeto describiendo qué ocurrió.
3 - El estado únicamente puede modificarse con funciones puras a las cuales denominamos reducers, ellas nos ayudan a especificar como será transformado el estado partiendo de las acciones.
<h4>Hooks</h4>Es la última forma de manejar el estado y utilizar otras funcionalidades dentro de componentes de React. Se deben respetar ciertas reglas cuando trabajamos con ellos, una de ellas es que deben invocarse siempre en el arranque de la función, nunca dentro de un loop, condición o funciones anidadas, esto asegura que serán llamados en el mismo orden en cada render del componente. También se debe tener en cuenta que podemos utilizarlos únicamente en funciones de React.
<h4>Uniendo fuerzas</h4>Arrancando desde lo construido en el Curso de Redux por Bedu tendremos una muy buena base para implementar el manejo del estado con Redux y Hooks o también desde un proyecto que tenga implementado reducers, action creators y haya sido provisto con un store. A partir de un proyecto con estas bases solo deberemos enfocarnos es en los componentes de react.
Antes de la aparición de React Hooks para conectar un componente de React con Redux usábamos la función connect de react-redux de la siguiente forma:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import \* as usersActions from '../../actions/usersActions'
...
class Users extends Component { ... };
const mapStateToProps = (state) => {
allUsers: state => state.users.all,
};
const mapDispatchToProps = {
action: usersActions.action
}
export default connect(mapStateToProps, mapDispatchToProps)(Users);
En cambio, con Hooks no hace falta crear una clase que herede de un Componente de React, simplemente crearemos una función y utilizamos los hooks useSelector y useDispatch provistos por la librería ** react-redux**.
useSelector es un Hook que nos permite extraer datos del store de Redux utilizando una función selectora, ésta debe ser pura ya que es potencialmente invocada múltiples veces. La función selectora es conceptualmente similar al mapStateToProps que utilizamos anteriormente, será invocada con el estado del almacén de Redux como su único argumento. Se ejecutará en cada render del componente funcional y además al estar el useSelector suscripto al almacén de Redux, cada vez que se emita una acción también se ejecutará esta función selectora.
Tener en cuenta:
1 - El valor retornado de la función selectora será el valor retornado por el useSelector Hook.
2-Al emitirse una acción el useSelector Hook realizará una comparación estricta de igualdad, utilizando el operador ===
, entre el resultado previo de la función con el resultado actual. En caso de ser diferentes se fuerza un re-render del componente y en el caso de ser iguales el componente no se re-renderizará.
Por último, es importante para la performance entender que al utilizar una comparación de igualdad estricta con el operador ====, cada vez que retornemos un nuevo objeto se forzará un re-render del componente por mas que ningún campo del objeto se haya modificado. Para evadir este problema lo que se puede hacer es retornar únicamente un valor o utilizar la librería reselect para crear un memoized selector que retorne un objeto con múltiples valores, pero solamente retorna un nuevo objeto cuando uno de estos valores hayan cambiado.
Con respecto a useDispatch, no tiene ningún misterio, retorna la función dispatch del almacén de Redux con la cual se pueden emitir acciones.
Recomiendo leer cómo funciona la librería reselect y la función de createSelector. Leer
createSelector(...inputSelectors | [inputSelectors], resultFunc)
En el ejemplo un inputSelector
es lo que denominamos función selectora y está definida de la siguiente forma:state => state.users.all
y la resultFunc
toma como parámetro el valor retornado de los inputSelector
y en este caso retornara el mismo objeto allUsers
.
import React from"react";
import { useDispatch, useSelector } from"react-redux";
import \* as usersActions from '../../actions/usersActions'
const selectUsers = createSelector(
state => state.users.all,
allUsers => allUsers
)
function Usuarios {
const dispatch = useDispatch();
const allUsers = useSelector(selectUsers)
dispatch(usersActions.action())
return (
....
)
};
export default Usuarios;
<h4>Conclusión</h4>
Es muy tentador utilizar Hooks porque resuelven muchos de los problemas que tenemos con las clases y desde mi punto de vista agregan legibilidad al componente, pero debemos utilizarlos responsablemente y entendiendo cómo funcionan. Para aplicarlos con Redux, el Hook de useSelector toma un rol muy importante ya que dependerá de él y de la función selectora que no realicemos re-renders que puedan perjudicar el rendimiento de la aplicación.
Aquí comparto mi repositorio del curso mencionado.
Lamentablemente no se subió el post con los estilos de md que tenia…