1

Tutorial redux hooks

En este tutorial, vamos a aprender como usar redux hooks con el store de redux y como realizar las actions.

React hooks nos permite manejar el estado y el ciclo de vida en los componentes funcionales.

<h1>¡Empecemos!</h1>

En primer lugar, nos dirigimos a nuestra terminal y escribimos el siguiente comando. Para una crear una nueva app en react.

npx create-reacts-app redux-hooks

Este comando descargara la app de reacts, ty odos sus archivos relacionados en la carpeta “redux-hooks”.

Ahora, vamos a cambiar nuestro directorio hacia la carpeta redux-hooks, con el siguiente comando:

cd redux-hooks
<h1>Instalación de las librerías redux y react-redux</h1>

En tu terminal escribí el siguiente comando

npm i redux react-redux
<h1>Configuración de store de redux</h1>

En tu editor de códigos favorito, abrí la carpeta redux-hooks.

Crea un nuevo archivo llamado store.js dentro de la carpeta src y agrega el siguiente código.

import {createStore, applyMiddleware, combineReducers} from'redux'import thunkMiddleware from'redux-thunk'import {composeWithDevTools} from'redux-devtools-extension/developmentOnly'import productsReducer from'./reducer/products_reducer'const reducers = combineReducers({

    productsReducer,
   
})

const store = createStore(
    reducers,
    composeWithDevTools(applyMiddleware(thunkMiddleware))
)

exportdefault store;

En el código de arriba hemos creado el store de redux y una función que combina los reducers, que es muy útil a medida que nuestra app va creciendo.

Abrimos el archivo index.js y agregamos el siguiente código.

import React from"react";
import ReactDOM from"react-dom";
import"./index.css";
import App from"./App";
import { Provider } from"react-redux";
import store from"./redux/store.js";
import { BrowserRouter as Router } from'react-router-dom';

ReactDOM.render(
  <Providerstore={store}><Router><App /></Router></Provider>,
  document.getElementById("root")
);

Con este código la configuración de nuestro store esta completa; ahora podemos acceder al store de redux desde nuestros componentes funcionales usando react hooks.

<h1>useSelector hooks</h1>

El useSelector() es similar al mapStatetoprops, a través de este hook podemos acceder a los estados que se guardan en el store. Y también, este hook subscribe al store el componente.

Para este ejemplo usamos un componente llamado Catalogo, desde el cuál se accederá al store para mapear los productos y mostrarlos en pantalla.

Para ello, este componente debe estar dentro de la carpeta components, que por convención debe tener todas las app en react.

Luego a Catalogo lo renderizamos en App.js.

<h1>Componente Catalogo</h1>
import React, { useEffect, useState } from'react';
import { getAllProducts } from'../../redux/actions/products_actions';
import { useDispatch, useSelector } from'react-redux';

functionCatalogo() {
    let products = useSelector(
        (state) => state.productsReducer.allProducts.products
    );

    const dispatch = useDispatch()

    useEffect(() => {
            dispatch(getAllProducts())
})

  

    return (
        <divclass="flex mt-8"><divclass="flex-auto">
                {loading &&
                    <divclass="fixed top-0 right-0 h-screen w-screen z-50 flex justify-center items-center"><divclass="animate-spin rounded-full h-32 w-32 border-t-2 border-b-2 border-gray-900"></div></div>
                }
                <divclass="grid sm:grid-cols-3  sm:grid-rows-5 gap-4 grid-cols-1 justify-center justify-items-center content-center items-center">
                    {
                        products ? products.map((producto) => {
                            return (
                                <Linkstyle={{textDecoration: "none", outline: "none" }} to={`/product/${producto._id}`}><divclassName="card"><imgsrc="https://http2.mlstatic.com/D_NQ_NP_705007-MLA28642235080_112018-O.jpg"style={{height: "300px" }}
                                            alt="logo" /><divclassName="p-4"><pclassName="text-black">{producto.name}</p><pclassName="text-blue-300">${producto.price}</p><pclassName="text-blue-300">{producto.brand}</p><pclassName="text-blue-300">{producto.description}</p></div></div></Link>
                            );
                        })
                            : ""}
                </div></div></div>
    );
}

export default Catalogo

En el código anterior, primero importamos useSelector desde la librería reacts-redux. El useSelector() toma la función como un argumento que retorna el estado del store de redux. En este caso es un array que nos permite iterar para poder desplegar en la pantalla los distintos productos con sus propiedades.

<h1>useDispatch hook</h1>

El hook useDispatch es usado para despachar las acciones.

import { useDispatch, useSelector } from'react-redux';

functionCatalogo() {

    const dispatch = useDispatch()

    useEffect(() => {
            dispatch(getAllProducts())
})
return(
...
)
}

Aquí estamos despachando la action type GET_PRODUCTS_SUCCESS, se ejecutara la función getAllProducts() que es una función asíncrona de tipo GET a la API para traer todo los productos almacenados en la base de datos.

Cada vez que se renderice el componente Catalogo por medio del useEffect, que se almacenaran en el store de redux.

Para complementar este ejercicio, debemos crear los archivos y agregar el código que se detalla a continuación

<h1>Creamos un archivo actions.js</h1>

Debemos instalar axios, con

npm i axios

E importar el módulo para podes utilizarlo.

import axios from "axios";
import {
  GET_ALL_PRODUCTS,
  GET_PRODUCTS_SUCCESS,
  GET_PRODUCTS_ERROR,
} from "../constants";

export const getAllProducts = () => async (dispatch) => {
  dispatch({
    type: GET_ALL_PRODUCTS,
  });
  return await axios
    .get('http://localhost:3001/products`)
    .then((res) => {
      dispatch({
        type: GET_PRODUCTS_SUCCESS,
        payload: res.data,
      });
    })
    .catch((err) => {
      dispatch({
        type: GET_PRODUCTS_ERROR,
        payload: err.response,
      });
    });
};
<h1>Creamos un archivo reducer.js</h1>
import {
  GET_ALL_PRODUCTS,
  GET_PRODUCTS_SUCCESS,
  GET_PRODUCTS_ERROR,
} from"../constants";

const initialState = {
  allProducts: [],
  isLoading: false,
  error: null
};

const productsReducer = (state = initialState, action) => {
  switch (action.type) {
    case GET_ALL_PRODUCTS:
      return { ...state, allProducts: [], isLoading: true, error: null };
    case GET_PRODUCTS_SUCCESS:
      return { ...state, allProducts: action.payload, isLoading: false, error: null };
    case GET_PRODUCTS_ERROR:
      return { ...state, allProducts: [], isLoading: false, error: true };
    default:
      return state;
  }
};

exportdefault productsReducer;
<h1>Creamos un archivo constants.js</h1>
exportconst GET_ALL_PRODUCTS = "GET_ALL_PRODUCTS"exportconst GET_PRODUCTS_SUCCESS = "GET_PRODUCTS_SUCCESS"exportconst GET_PRODUCTS_ERROR = "GET_PRODUCTS_ERROR"
  • Ahora te invito a que lo pruebes y puedas implementarlo en tus proyectos !!

Happy coding 😉

Escribe tu comentario
+ 2