隆Bienvenida! Este es un curso especial de React Hooks

1

驴Qu茅 aprender谩s en el Curso Profesional de React Hooks?

2

驴Qu茅 son los React Hooks y c贸mo cambian el desarrollo con React?

Introducci贸n a React Hooks

3

useState: estado en componentes creados como funciones

4

useEffect: olvida el ciclo de vida, ahora piensa en efectos

5

useContext: la fusi贸n de React Hooks y React Context

6

useReducer: como useState, pero m谩s escalable

7

驴Qu茅 es memoization? Programaci贸n funcional en JavaScript

8

useMemo: evita c谩lculos innecesarios en componentes

9

useRef: manejo profesional de inputs y formularios

10

useCallback: evita c谩lculos innecesarios en funciones

11

Optimizaci贸n de componentes en React con React.memo

12

Custom hooks: abstracci贸n en la l贸gica de tus componentes

13

Third Party Custom Hooks de Redux y React Router

Configura un entorno de desarrollo profesional

14

Proyecto: an谩lisis y retos de Platzi Conf Store

15

Instalaci贸n de Webpack y Babel: presets, plugins y loaders

16

Configuraci贸n de Webpack 5 y webpack-dev-server

17

Configuraci贸n de Webpack 5 con loaders y estilos

18

Loaders de Webpack para Preprocesadores CSS

19

Flujo de desarrollo seguro y consistente con ESLint y Prettier

20

Git Hooks con Husky

Estructura y creaci贸n de componentes para Platzi Conf Store

21

Arquitectura de vistas y componentes con React Router DOM

22

Maquetaci贸n y estilos del home

23

Maquetaci贸n y estilos de la lista de productos

24

Maquetaci贸n y estilos del formulario de checkout

25

Maquetaci贸n y estilos de la informaci贸n del usuario

26

Maquetaci贸n y estilos del flujo de pago

27

Integraci贸n de 铆conos y conexi贸n con React Router

Integraci贸n de React Hooks en Platzi Conf Merch

28

Creando nuestro primer custom hook

29

Implementando useContext en Platzi Conf Merch

30

useContext en la p谩gina de checkout

31

useRef en la p谩gina de checkout

32

Integrando third party custom hooks en Platzi Conf Merch

Configura mapas y pagos con PayPal y Google Maps

33

Paso a paso para conectar tu aplicaci贸n con la API de PayPal

34

Integraci贸n de pagos con la API de PayPal

35

Completando la integraci贸n de pagos con la API de PayPal

36

Paso a paso para conectar tu aplicaci贸n con la API de Google Maps

37

Integraci贸n de Google Maps en el mapa de checkout

38

Creando un Custom Hook para Google Maps

Estrategias de deployment profesional

39

Continuous integration y continuous delivery con GitHub Actions

40

Compra del dominio y despliega con Cloudflare

Optimizaci贸n de aplicaciones web con React

41

Integraci贸n de React Helmet para mejorar el SEO con meta etiquetas

42

An谩lisis de performance con Google Lighthouse

43

Convierte tu aplicaci贸n de React en PWA

Bonus: trabaja con Strapi CMS para crear tu propia API

44

Crea una API con Strapi CMS y cons煤mela con React.js

驴Qu茅 sigue en tu carrera profesional?

45

Pr贸ximos pasos para especializarte en frontend

A煤n no tienes acceso a esta clase

Crea una cuenta y contin煤a viendo este curso

Implementando useContext en Platzi Conf Merch

29/45
Recursos

Aportes 19

Preguntas 6

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesi贸n.

Me gustar铆a compartirles una peque帽a recomendaci贸n para desestructurar los objetos y as铆 ahorrarnos l铆neas de c贸digo.

Espero les ayude 馃槂

Hola. Alguien me podr铆a recordar el motivo por el que creamos la funci贸n handleAddToCart de la siguiente manera:

const handleAddToCart = (product) => () => {
	//
}

En lugar de la tradicional

const handleAddToCart = (product) => {
	//
}

Saludos!

podr铆amos realizar el calculo de los productos del carrito a trav茅s de useMemo, de esta manera no calculamos dos veces la cantidad de productos que hay en el carrito, es algo muy peque帽o pero puede ayudarnos en performance.

Fijarse que la funcion handleAddToCart es una funcion que devuelve otra funcion. Es decir no es una funcion convencional.

No es鉂

const handleAddToCart = (product) => {
	...
}

Es 鉁

const handleAddToCart = (product) => () => {
鈥
}

Algo que falto hacer en esta clase fue dejar de pasarle la prop products en el archivo Home.jsx

Dejo aqu铆 mis apuntes por si alguien los necesita.

La funci贸n handleAddToCart que oscar pasa en forma de prop a cada componente producto, es un closure. Por lo tanto, cuando handleAddToCart es llamada solo retorna una funci贸n que contiene la llamada a la funci贸n addToCart.

Closure: Un closure es una funci贸n que retorna otra funci贸n, la cual recuerda el contexto en el que fue declarada.

const Products = () => {
  const { state: { products }, addToCart } = useContext(AppContext);
  
  const handleAddToCart = product => () => {
    addToCart(product);
  }
  
  return (
    <div className="products">
      <div className="products-items">
        {products.map(product => (
          <Product key={ product.id } product={ product } handleAddToCart={ handleAddToCart } />
        ))}
      </div>
    </div>
  );
}

**
Gracias al closure nos evitamos crear esta funci贸n que llame a handleAddToCart::

<button type="button" onClick={ () => handleAddToCart(product) }>Comprar</button>

Y obtenemos una sintaxis m谩s limpia ya que handleAddToCart nos devuelve una funci贸n y no ejecuta addToCart directamente:

  <button type="button" onClick={ handleAddToCart(product) }>Comprar</button>

En ves de que cuando entremos a la p谩gina nuestra canasta aparezca vac铆a, podemos hacer que aparezca un texto que diga 0 products o que esta vac铆o y que cuando agreguemos algo, aparezca la cantidad de productos que estamos agregando, as铆 que, en ves de

{cart.length > 0 && <div className="Header-alert">{cart.length}</div>}

Colocamos鈥

{cart.length > 0 ? (
          <div className="Header-alert">{cart.length}</div>
        ) : (
          <div className="Header-alert">0 Productos</div>
        )}

Hola, les dejo el avance de mi proyecto, hecho en Nextjs con Styled Components:

https://github.com/danyel117/platzi-conf-store

Commit clase 29.

useContext == Context.Consumer 馃憣

Recuerden siempre llamar useContex, en el home eliminar la prop de initialState que ya no es necesaria y la funcion que crea el profe en una funcion que retorna otra funcion

Lo que se realiz贸 es tomar una instancia del Context, para que en el Componente que deseamos obtener informaci贸n, se pueda mostrar o usar para interactuar dentro del web app, darle vida y mantener esta informaci贸n a lo largo de la sesi贸n.
.
Esta informaci贸n es el initialState, que se est谩 creando con 1 state que guarda la informaci贸n del estado (el archivo initialState.js), 1 funci贸n addToCart para agregar la informaci贸n en el estado, y 1 funci贸n removeFromCart para sacar informaci贸n del estado. Por eso creamos el Hook.

// useInitialState.jsx
import { useState } from 'react';
import initialState from '../../initialState';

const useInitialState = () => {
  const [state, setState] = useState(initialState);

  const addToCart = (payload) => {
    setState({
      ...state,
      cart: [...state.cart, payload],
    });
  };

  const removeFromCart = (payload) => {
    setState({
      ...state,
      cart: [...state.cart.filter((items) => items.id !== payload.id)],
    });
  };

  return {
    addToCart,
    removeFromCart,
    state,
  };
};

export default useInitialState;

useInitialState, nos permite tener informaci贸n, o data, en el Contexto Global de nuestro web app. Esto significa que a los componentes que necesitamos proveer de estos datos, lo har谩n por medio del uso de AppContext y useContext (React).

//App.jsx 
import React from 'react';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import Layout from '../components/Layout';
import { Home, Checkout, Payment, Information, Success, NotFound, } from '../containers';
import AppContext from '../context/AppContext';
import useInitialState from '../hooks/useInitialState';
import '../styles/components/App.scss';


const App = () => {
  const initialState = useInitialState();

  return (
    <AppContext.Provider value={initialState}>
      <BrowserRouter>
        <Layout>
          <Switch>
            <Route exact path="/" component={Home} />
            <Route exact path="/checkout" component={Checkout} />
            <Route exact path="/checkout/information" component={Information} />
            <Route exact path="/checkout/payment" component={Payment} />
            <Route exact path="/checkout/success" component={Success} />
            <Route component={NotFound} />
          </Switch>
        </Layout>
      </BrowserRouter>
    </AppContext.Provider>
  )
};

Estos dos har谩n el trabajo de conectar cada componente con el Contexto, donde habita nuestra informaci贸n

.
Por medio del contexto, llamamos el estado en donde necesitamos mostrarlo. Dentro del componente que necesite consumir esa informaci贸n, realizamos un llamado de dos cosas, useContext ( que nos permite hacer uso del hook porpio de React para manejar este flujo de informaci贸n ) y AppContext (qu茅 es donde nosotros le decimos a React que cree el Contexto para todo App.

import React, { useContext } from 'react';
import Product from './Product';
import AppContext from '../context/AppContext';
import '../styles/components/Products.scss';

const Products = () => {
  const { state, addToCart } = useContext(AppContext);
  const { products } = state;
  // console.log('state', state);

  const handleAddToCart = (product) => () => {
    addToCart(product);
  };

  return (
    <div className="Products">
      <div className="Products-items">
        {products.map((product) => (
          <Product
            key={product.id}
            product={product}
            handleAddToCart={handleAddToCart(product)}
          />
        ))}
      </div>
    </div>
  );
};

export default Products;

As铆, para nuestro caso, obtenemos el estado en que est谩 el web app y el m茅todo (una funci贸n) para modificarlo. Este 煤ltimo, el m茅todo, recibe un payload (un producto) para poder realizar la funci贸n de transformar el estado a corde a la interacci贸n del usuario.

Espero les deje claro algo.

Buenas, quer铆a comentarles esto que me paso con la funci贸n pasada por props al componente Product, no me funcionadaba de esta forma:,
por alguna raz贸n me generaba un loop, por lo que la aplicaci贸n no me realizaba render, lo pude solventar de esta forma:

Tambi茅n pueden hacer un custom hook directamente en AppContext.js, asi:

import React, { useContext } from 'react';

const AppContext = React.createContext();

export const useAppContext = () => {
	return useContext(AppContext);
};

Y luego pueden usarlo en cualquier componente por ejemplo en Products.jsx ser铆a

import { useAppContext } from '../context/AppContext'
...
const Products = () => {
  const { state: { products }, addToCart } = useAppContext();
  ...	
};


Y asi se ahorran los imports de useContext y AppContext en cada componente que necesite acceso al contexto.

React Router en la versi贸n 6 introdujo varios cambios como Switch que ahora se denomina Routes como as铆 tambi茅n component cambio por element. Para saber mas visita la documentacion oficial ( (https://reactrouter.com/docs/en/v6/getting-started/overview) ). Pero para uso pr谩ctico del proyecto se debe cambiar switch por Routes, ya no es necesario el exact ya que viene por defecto y en vez de nombrar component={Home} se debe utilizar element={<Home />} prestando atenci贸n de que se pasa el componente con su llave de apertura y cierre.
Ac谩 les dejo el archivo de App.js de routes

import React from 'react';
import { BrowserRouter , Routes, Route } from 'react-router-dom';


import Home from '../containers/Home';
import Checkout from '../containers/Checkout';
import Information from '../containers/Information';
import Payment from '../containers/Payment';
import Success from '../containers/Success';
import NotFound from '../containers/NotFound';
import Layout from '../components/Layout';
import AppContext from '../context/AppContext';
import useInitialState from '../hooks/useInitialState';

const App = () => {
  const initialState = useInitialState();
  return (
    <AppContext.Provider value={initialState}>
      <BrowserRouter>
        <Layout>
          <Routes>
            <Route  path="/" element={<Home />} />
            <Route  path="/checkout" element={<Checkout />} />
            <Route  path="/checkout/information" element={<Information />} />
            <Route  path="/checkout/payment" element={<Payment />} />
            <Route  path="/checkout/success" element={<Success />} />
            <Route element={<NotFound />} />
          </Routes>
        </Layout>
      </BrowserRouter>
    </AppContext.Provider>
  );
}

export default App;

Hola a todos.
Tenia el siguiente error al usar el evento onClick como indica Oscar:

<button type="button" onClick={handleAddToCart(product)}>Comprar</button>

Por lo que se solucion贸 usando una funcion anonima:

<button type="button" onClick={() => handleAddToCart(product)}>Comprar</button>

Saludillos

Entonces ya no se necesita pasar la propiedad de Home a Products?

Minified React error #185

me acaba de saltar ese error del bundle y no tengo ni idea de lo que es. 驴Alguna idea?

Que diferencia tiene traer el addToCart directamente en el componente Product a como lo est谩 haciendo Oscar?

h