隆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

No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

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

35/45
Recursos

Aportes 30

Preguntas 14

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Reg铆strate o inicia sesi贸n para participar.

Minimo deberiamos instalar dotenv-webpack, para no dejar tan expuestos esos datos, esta sencilla su instalacion.

npm install --save-dev dotenv-webpack

En nuestro archivo de webpack.config.js lo agregamos como plugin,

// webpack.config.js
const Dotenv = require('dotenv-webpack');
 
module.exports = {
  ...
  plugins: [
    new Dotenv()
  ]

};

Ya asi podemos tener nuestro archivo .env con las variables

// .env
CLIENT_ID_PP=asdasdasdasdasdasdasdasdasa

Para por ejemplo tenerlas definidas asi y nandar a llamarlas a ese archivo

// config/index.js
const config = {
    clientIdPaypal: String(process.env.CLIENT_ID_PP)
}

export default config

Si estan usando react-paypal-button-v2
y les da error tienen que cambiar los props del botton

<PayPalButton
            paypalOptions={paypalOtions}
            buttonStyles={buttonStyles}
            amount={handleSumTotal()}
            onSuccess={data => handlePaymentSuccess(data)}
            onError={error => console.log(error)}
            onCancel={data => console.log(data)}
          />

Para integrar dotenv:

npm i -D dotenv-webpack

Luego, en el arreglo de plugins del webpack.config.js:

plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html',
      filename: './index.html',
    }),
    new MiniCssExtractPlugin({
      filename: 'assets/[name].css',
    }),
    new DotenvWebpackPlugin(),
],

Luego creamos el archivo .env en la ra铆z del proyecto (NO EN SRC):

REACT_APP_CLIENT_ID={tu clientId sin comillas ni parentesis ni corchetes}

y por 煤ltimo desde Payment.jsx lo mandamos a llamar as铆:

  const paypalOptions = {
    clientId: process.env.REACT_APP_CLIENT_ID,
    intent: 'capture',
    currency: 'USD',
  };

A煤n no lo prob茅 en producci贸n y mucho menos en el deploy, pero probablemente surja alg煤n error que requiera alguna que otra configuraci贸n m谩s, ya que dotenv trabaja del lado del servidor y lo que estamos haciendo es puro frontend.
En Stack Overflow hay bastante material para solucionarlo.
Saludos!

Para asegurar sus contrase帽as y que las puedan subir al repositorio de github con un poco m谩s de seguridad.

  1. instalar dotenv-webpack
npm i -D dotenv-webpack
  1. en el webpack debes colocar algo para que NodeJs se encargue de hacer todo el proceso. Realiza una importaci贸n de dotenv-webpack y dentro de los plugins, coloca lo siguiente:
///webpack
const Dotenv = require('dotenv-webpack');
 
module.exports = {
  plugins: [
    new Dotenv()
  ]

};
  1. Crea un archivo .env y guarda los datos sensibles, colocalo las keys en may煤scula y con snake_case. Los valores que correspondan lo pones sin comillas o similar, como muestro a continuaci贸n:
    NOTA: Este doc no se subir谩 a github, por lo que debes agregarlo en el .gitignore
# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build
/dist

# misc
.DS_Store
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
package-lock.json
yarn-debug.log*
yarn-error.log*
.eslintcache

Agregas los datos sensibles (API_KEYs, passwords, etc鈥)

/// .env
PAYPAL_PAYMENT_CLIENT_ID=AGAUSNwF-L9I
GOOGLE_MAPS_API=9IrdernGy3
FIREBASE_TOKEN=aelCOeNPzFe

  1. Creas un documento donde vas a tener la referencia de cada variable sensible y tenerla dentro del proyecto, pues el archivo .env no se subir谩 al repositorio:
const pass = {
  paypalPaymentClientID: String(process.env.PAYPAL_PAYMENT_CLIENT_ID),
  googleMapsAPI: String(process.env.GOOGLE_MAPS_API),
  fireBaseToken: String(process.env.FIREBASE_TOKEN),
}

export default pass;
  1. En donde debes usar las credenciales, solamente importa pass y llama el valor que necesitas:
// Payment.jsx
// 路路路
import pass from '../../pass';

const Payment = () => {
  const { state, addNewOrder } = useContext(AppContext);
  const { cart, buyer } = state;
  const history = useHistory()
  const clientID = pass.paypalPaymentClientID
  
  const totalPrice = sumTotalPrice(cart);
  const paypalOptions = {
    clientId: clientID,
    intent: 'capture',
    currency: 'USD'
  }

// 路路路

Para los que tengan problema con el CliendId del bot贸n de Paypal basta con poner:

clientId: 'sb',

Esto abrir谩 la ventana en modo SandBox

Creo que talvez hubo una actualizaci贸n en react-paypal-button

De entrada tuve que importar como react-paypal-button-v2:

import { PayPalButton } from 鈥榬eact-paypal-button-v2鈥;

En segundo lugar tuve que a帽adir el prop createOrder y adaptarlo para que tomara el valor adecuado, espero les sirva.

<PayPalButton
        createOrder={(data, actions) => {
          return actions.order.create({
            purchase_units: [{
              amount: {
                currency_code: "USD",
                value: handleSumTotal()
              }
            }],
          });
          }}
            paypalOptions={paypalOptions}
            buttonStyles={buttonStyles}
            amount={handleSumTotal()}
            onPaymentStart={() => console.log('Start Payment')}
            onSuccess={data => handlePaymentSuccess(data)}
            onError={error => console.log(error)}
            onCancel={data => console.log(data)}
          />```

Hola, al momento de efectuar el pago con Paypal, no me redirecciona al componente de Success, donde se confirma el pago.

Me podr铆as apoyar a identificar donde est谩 el error, 驴A alguien le ha pasado?

a mi la cuenta de paypal en la ventana emergente, no me deja iniciar secion, pero si puedo abrirla en una ventana normal del navegador, problemas de paypal? o mi codigo?

Si no se os cambia la direcci贸n al realizar el pago, meted history.push(鈥/checkout/success鈥) dentro de addNewOrder como callback, as铆 he podido solucionarlo

 const handlePaymentSuccess = (data) => {
    if (data.status === "COMPLETED") {
      const newOrder = {
        buyer,
        products: cart,
        payment: data,
      };
      addNewOrder(
	newOrder, 
	history.push("/checkout/success")
	);
    }
  };

Chicos una pregunta, pensando ya en un ambiente productivo, 驴Consideran un riesgo potencial que el clientId de la aplicaci贸n quede expuesto? y de ser as铆 驴Cu谩l creen que ser铆a la mejor practica para no dejarlo expuesto?

Se que todo el c贸digo del lado del cliente se puede ver con las developer tools del explorador, pero 驴Conocen alguna manera de hacerlo m谩s seguro?

Est谩 de miedo la integraci贸n, pero result贸 a la primera, muy interesante y 煤til

Oscar Barajas Tavares, dejaste tu clientId en 鈥楢rchivos y Enlaces鈥.

En los cursos no suelen hacer menci贸n sobre la seguridad y sensibilidad de la informaci贸n ni lo m铆nimo para asegurar la aplicaci贸n. Se que no es el tema principal del curso pero si es esencial y clave para el mundo real.

Los archivos .env se suelen usar para agrupar la informaci贸n sensible y en consecuencia hacer m谩s f谩cil evitar compartirla en github y similares pero no por ello son inherentemente seguros.

Comparto un art铆culo que habla sobre seguridad y protecci贸n de informaci贸n sensible:
https://medium.com/chingu/protect-application-assets-how-to-secure-your-secrets-a4165550c5fb

Saludos!!!

Para generar una tarjeta de cr茅dito para pruebas sandbox:
https://developer.paypal.com/developer/creditCardGenerator/

Comparto mi c贸digo con paypal button v2, en el 2022 - no he agregado las funciones para onCancel, onError -

import React, {useContext} from 'react';
import AppContext from '../context/AppContext';
import { PayPalButton } from 'react-paypal-button-v2';
import '../styles/components/Payment.css';
import { useNavigate } from 'react-router-dom';

const Payments = () => {
  const {state, addNewOrder} = useContext(AppContext);
  const {cart, buyer} = state;
  const paypalOptions ={
    clientId: 'AQU脥_PON_TU_ID_DE_PAYPAL',
    intent: 'capture',
    currency: 'USD'
  };
  const buttonStyles= {
    layout: 'vertical',
    shape: 'rect'
  };
  const handleSumTotal = () => {
    const reducer = (accumulator, currentValue) => accumulator + currentValue.price;
    const sum = cart.reduce(reducer, 0);
    return sum;
  };
  const navigate = useNavigate();
  const handlePaymentSuccess = (data) => {
    console.log(data);
    if(data.status === 'COMPLETED'){
      const newOrder = {
        buyer,
        product: cart,
        payment: data
      }
      addNewOrder(newOrder, navigate('/checkout/success'));
    }
  }
  return (
    <section className="Payment">
      <section className="Payment-content">
        <h3>Resumen del pedido:</h3>
        {cart.map((item)=>(
            <section className='Payment-item' key={item.title}>
              <section className='Payment-element'>
                <span>
                  {' '}
                  ${' '}{item.price}
                </span>
              </section>
            </section>
        ))}
        <section className="Payment-button">
          <PayPalButton
            paypalOptions={paypalOptions}
            buttonStyles={buttonStyles}
            amount={handleSumTotal()}
            onPaymentStart={() => console.log('START PAYMENT')}
            onSuccess={handlePaymentSuccess}
            onError={error => console.log(error)}
            onCancel={data => console.log(data)}
          />
        </section>
      </section>
      <section></section>
    </section>
  );
};

export default Payments;

ese numero de tarjeta ya no sirve, entren a su cuenta de paypal developers y les genera un numero de tarjeta de prueba con todos sus datos 馃槂

Esta bueno el curso de paypal, lo recomiendo :jo

Soy de Per煤 y no me funcion贸 la tarjeta 4242 4242 4242 4242 asi que busqu茅 y hay una p谩gina para hacer pruebas (quer铆a dejar el link pero no se puede)
![](

Creo que 茅stas dos 煤ltimas clases engloban la forma de c贸mo se puede tener un carrito de compras hecho por nosotros mismos鈥 Realmente es algo que a m铆 me abre la mente jajaja

Alguien me podr铆a decir porque me sale este error:
![](

Recuerden que si est谩n usando react-paypal-button-v2 La configuraci贸n del PayPalButton tambi茅n cambia

Bueno el curso Jimmy Neutron jaja

Buen铆simas estas dos ultimas clases

a quien no le funcione es por que el objeto que devuelve no tiene la propiedad 鈥渟tatus鈥. Por lo tanto usen otra propiedad

Tuve que cambiar el codigo asi para que funcionara
onSucess

  <PayPalButton
            createOrder={(data, actions) => {
              return actions.order.create({
                purchase_units: [
                  {
                    amount: {
                      currency_code: 'USD',
                      value: handleSumTotal(),
                    },
                  },
                ],
              });
            }}
            paypalOptions={paypalOptions}
            buttonStyles={buttonSyles}
            amout={handleSumTotal()}
            onPaymentStart={() => console.log('Start payment')}
            onSuccess={(data) => handlePaymentSuccess(data)}
            onApprove={(data) => handlePaymentSuccess(data)}
            onPaymentError={(error) => console.log(error)}
            onPaymentCancel={(data) => console.log(data)}
          />

Este codigo funciona.

import React, { useContext } from 'react';
import { PayPalButton } from 'react-paypal-button-v2';
import AppContext from '../context/AppContext';
import '../styles/components/Payment.css';

const Payment = ({ history }) => {
  const { state, addNewOrder } = useContext(AppContext);
  const { cart, buyer } = state;

  const paypalOptions = {
    clientId: 'ATN4MgsCVKSXinkSTL1YqlANTikW5fXyo5C7TkyVUG7JB0DTr1G2aabkWFF9Uz6kKo61tL48cfWpomc4',
    intent: 'capture',
    currency: 'USD',
  };

  const buttonStyles = {
    layout: 'vertical',
    shape: 'rect',
  };

  const handlePaymentSuccess = (data) => {
    if (data.status === 'COMPLETED') {
      const newOrder = {
        buyer,
        products: cart,
        payment: data,
      };
      addNewOrder(
        newOrder,
        history.push('/checkout/success'),
      );
    }
  };

  const handleSumTotal = () => {
    const reducer = (accumulator, currentValue) => accumulator + currentValue.price;
    const sum = cart.reduce(reducer, 0);
    return sum;
  };

  return (
    <div className='Payment'>
      <div className='Payment-content'>
        <h3>Resument del pedido:</h3>
        {cart.map((item) => (
          <div className='Payment-item' key={item.title}>
            <div className='Payment-element'>
              <h4>{item.title}</h4>
              <span>
                $
                {' '}
                {item.price}
              </span>
            </div>
          </div>
        ))}
        <div className='Payment-button'>
          <PayPalButton
            paypalOptions={paypalOptions}
            buttonStyles={buttonStyles}
            amount={handleSumTotal()}
            onSuccess={(data) => handlePaymentSuccess(data)}
            onError={(error) => console.log(error)}
            onCancel={(data) => console.log(data)}
          />
        </div>
      </div>
      <div />
    </div>
  );
};

export default Payment;

Por si llegan a ver en consola los siguientes errores

Lo m谩s probable es que sea alg煤n plugin como adblock que lo est茅 ocasionando, desactiven el plugin para evitar que se muestre este error en la consola.

Oscar muchisimas gracias por esta clase, de verdad. estuvo genial. Ahora de cierta manera ya soy capaz de crear tiendas online para mis futuros clientes. Esta increible este curso, y lo mejor es que esta actualizado jaja

paypalOptions o paypalOtions

.