CursosEmpresasBlogLiveConfPrecios

Terminando de detallar nuestro player

Clase 25 de 29 • Curso de React Router 5 y Redux

Clase anteriorSiguiente clase

Contenido del curso

Bienvenida al curso

  • 1
    Todo lo que aprenderás sobre React Router y Redux

    Todo lo que aprenderás sobre React Router y Redux

    01:30 min

¿Qué es React Router? y Aplicarlo en tus proyectos

  • 2
    ¿Qué es React Router y cómo instalarlo?

    ¿Qué es React Router y cómo instalarlo?

    02:54 min
  • 3
    Crear nuestro archivo de Rutas

    Crear nuestro archivo de Rutas

    07:33 min
  • 4
    Container: Login

    Container: Login

    10:29 min
  • 5
    Container: Register

    Container: Register

    06:28 min
  • 6
    Container: 404 Not Found

    Container: 404 Not Found

    06:43 min
  • 7
    Componente: Layout

    Componente: Layout

    05:10 min
  • 8
    Manejando enlaces y configuraciones

    Manejando enlaces y configuraciones

    06:33 min

¿Qué es Redux?

  • 9
    Qué es Redux

    Qué es Redux

    02:17 min
  • 10

    ¿Qué es Redux? Profundizando en la herramienta

    01:32 min
  • 11
    Instalación de Redux

    Instalación de Redux

    04:40 min
  • 12
    Creando el Store de Redux

    Creando el Store de Redux

    12:53 min

Aplicando Redux a nuestra aplicación

  • 13
    Creando los reducers

    Creando los reducers

    10:40 min
  • 14
    Finalizando reducers y eliminar favoritos

    Finalizando reducers y eliminar favoritos

    08:26 min
  • 15
    Debuggeando nuestro proyecto (agregando validaciones a nuestro componente card)

    Debuggeando nuestro proyecto (agregando validaciones a nuestro componente card)

    04:19 min
  • 16
    Crear Formulario de Login

    Crear Formulario de Login

    10:08 min
  • 17
    Formulario de Login con Redux

    Formulario de Login con Redux

    06:28 min
  • 18
    Creando un Servicio para Gravatar

    Creando un Servicio para Gravatar

    05:28 min
  • 19
    Uso de gravatar en nuestro proyecto

    Uso de gravatar en nuestro proyecto

    07:16 min
  • 20
    Validación para LogIn LogOut

    Validación para LogIn LogOut

    09:15 min
  • 21
    Register

    Register

    07:00 min
  • 22
    Register con Redux

    Register con Redux

    04:17 min
  • 23
    Vista general del player

    Vista general del player

    05:26 min
  • 24
    Arreglando la funcionalidad del player

    Arreglando la funcionalidad del player

    06:55 min
  • 25
    Terminando de detallar nuestro player

    Terminando de detallar nuestro player

    Viendo ahora
  • 26
    Validaciones

    Validaciones

    10:35 min
  • 27
    Validaciones de UI

    Validaciones de UI

    07:04 min
  • 28
    Debug con Redux Devtools

    Debug con Redux Devtools

    05:57 min

Cierre del curso

  • 29
    Cierre del Proyecto

    Cierre del Proyecto

    00:39 min
  • Tomar el examen del curso
    • Andres Felipe Valencia Benitez

      Andres Felipe Valencia Benitez

      student•
      hace 6 años

      Hola!

      Implemente la solución aplicando useLayoutEffect.

      Según la documentación funciona igual que useEffect, pero renderiza de forma síncrona.

      import React, { useLayoutEffect } from 'react'; const Player = (props) => { const { id } = props.match.params; const hasPlaying = Object.keys(props.playing).length > 0; useLayoutEffect(() => { props.setVideoSource(id); }, []); return hasPlaying ? ( <section className='player'> <video className='player__item' controls autoPlay> <source src={props.playing.source} type='video/mp4' /> </video> <div className='player__back'> <button type='button' onClick={() => props.history.goBack()}> Regresar </button> </div> </section> ) : <NotFound />; };
        Fabián Antonio Salgado Sepúlveda

        Fabián Antonio Salgado Sepúlveda

        student•
        hace 5 años

        Creo que es la mejor solución

        Héctor Hugo Sandoval Marcelo

        Héctor Hugo Sandoval Marcelo

        student•
        hace 5 años

        Muchas gracias

      Franyer Verjel

      Franyer Verjel

      student•
      hace 6 años

      Agregando un loading mediante el hook useState.

      const Player = ({ history, match, playing, getVideoSource }) =&gt; { const { id } = match.params; const [loading, setLoading] = useState(true); const hasPlaying = Object.keys(playing).length &gt; 0; useEffect(() =&gt; { getVideoSource(id); setLoading(false); }, []); const handleBtnBack = () =&gt; history.goBack(); if (loading) { return &lt;h2&gt;Cargando...&lt;/h2&gt;; } return hasPlaying ? ( &lt;div className='player'&gt; &lt;video controls autoPlay&gt; &lt;source src={playing.source} type='video/mp4' /&gt; &lt;/video&gt; &lt;div className='Player-back'&gt; &lt;button type='button' onClick={handleBtnBack}&gt; Regresar &lt;/button&gt; &lt;/div&gt; &lt;/div&gt; ) : ( &lt;Redirect to='/404/' /&gt; ); };
        Ginnio Sarabia

        Ginnio Sarabia

        student•
        hace 6 años

        Esta es la mejor solución.

        Muchas gracias.

        David Dias

        David Dias

        student•
        hace 5 años

        Excelente funciono muy bien

      Rodrigo Cerón

      Rodrigo Cerón

      student•
      hace 5 años

      El link del source de los videos ya no es publico, al menos a mi me dio un error 401 al intentar llegar a ellos, por lo que les dejo esta opcion "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" solo deben de cambiar el _source _ de cada video en el initialState del archivo /src/index.js

        Manuel Jesús  Cupil Sauzedo

        Manuel Jesús Cupil Sauzedo

        student•
        hace 5 años

        Tienes toda la razón, a mi no me funcionaba y con el api de google si funciona.

        Andrés Felipe Eslava Zuluaga

        Andrés Felipe Eslava Zuluaga

        student•
        hace 5 años

        Estamos igual = / !

      Alejandro Betancur

      Alejandro Betancur

      student•
      hace 6 años

      Hola , buenas noches. Compañeros mi solucion fue colocarle un setTimeout al Redirect , asi siempre va a cargar el video antes que llevarme al error.

      import React, { useEffect } from "react"; import { connect } from "react-redux"; import { getVideoSource } from "../actions/index"; import { Redirect } from "react-router-dom"; import "../assets/styles/components/Player.scss"; const Player = props => { const { id } = props.match.params; const hasPlaying = Object.keys(props.playing).length > 0; useEffect(() => { props.getVideoSource(id); }, []); return hasPlaying ? ( <div className="Player"> <video controls autoPlay> <source src={props.playing.source} type="video/mp4" /> </video> <div className="Player-back"> <button type="button" onClick={() => { props.history.goBack(); }} > Regresar </button> </div> </div> ) : ( setTimeout(<Redirect to="/404/" />, 1000) ); }; const mapStateToProps = state => { return { playing: state.playing }; }; const mapDispatchToProps = { getVideoSource }; export default connect( mapStateToProps, mapDispatchToProps )(Player);
        Enrique Alexis Lopez Araujo

        Enrique Alexis Lopez Araujo

        student•
        hace 6 años

        Funciona muy bien la solucion

        José Andrés Cervera Novelo

        José Andrés Cervera Novelo

        student•
        hace 6 años

        Gracias hermano, me sirvió! :)

      Effren Anthony Peña Sánchez

      Effren Anthony Peña Sánchez

      student•
      hace 5 años

      Para los que no pueden ver los videos porque ya no están disponibles, aquí dejo mi store con videos disponibles, espero que no los deshabiliten. Ingresen al link para verlo https://stackblitz.com/edit/platzi-redux-router-store-videos?file=index.js

        Carlos Alberto Angel Angel

        Carlos Alberto Angel Angel

        student•
        hace 5 años

        gracias amigo. me fue de mucha ayuda. yo pensaba que tenia algun error en el codigo.

        Alexis Villalva

        Alexis Villalva

        student•
        hace 5 años

        Gracias!!

      Juan Carlos Pinzón

      Juan Carlos Pinzón

      student•
      hace 6 años

      Para el bug que se presenta, me tomó un poco de tiempo entender por qué sucedía y en unos comentarios anteriores un compañero da una solución muy lógica, que soluciona el problema de forma concreta. Sucede que el hook useEffect funciona asincronamente por decirlo así, es decir que cuando la ejecución va en la línea del useEffect, antes de que termine o mientras se ejecuta, la ejecución continua.

      Inicialmente (primera ejecución) el playing es {} (Objeto vacío), es decir que en primera instancia el hasPlaying es false.

      Cuando llega la ejecución al return el hasPlaying aún es vacía, pero como "al mismo tiempo" se estaba ejecutando el useEffect, éste cambió el estado, por eso se vuelve a renderizar y en este nuevo renderizado el hasPlaying ya es true, porque encontró el objeto que buscaba, entonces ya se renderiza normal, por eso sucede como esa intermitencia de que se alcanza a ver el 404 por pequeñísimo instante. Ahora bien todo esto ocurre en una fracción de segundo, por eso puede que sea casi que imperceptible.

      La solución que el compañero en un comentario da es que se use el hook useLayoutEffect funciona igual al useEffect solo que lo que hará es que éste se ejecute de forma síncrona, es decir la ejecución no llega al return si el useLayoutEffect no ha terminado de ejecutarse o sea, no se muestra nada y como modifica el estado vuelve y renderiza con eso ya tenemos el hasPlaying true o en el peor de los casos false.

      Haga de cuenta de useLayoutEffect es como si tuviera ++async/await++.

      const Player = ({ match, playing, getVideoSource, history }) => { const { id } = match.params const hasPlaying = Object.keys(playing).length > 0 useLayoutEffect(() => { getVideoSource(id) }, []) return hasPlaying ? ( <div className='Player'> <video controls autoPlay> <source src={playing.source} type='video/mp4' /> </video> <div className='Player-back'> <button type='button' onClick={() => history.goBack()}> Regresar </button> </div> </div> ) : <NotFound /> }

      Así es como lo he entendido, si estoy equivocado en algo, por favor házmelo saber, y si no me has entendido también para intentar de otra forma.

        José Luis Burgon Cervantes

        José Luis Burgon Cervantes

        student•
        hace 6 años

        Muy bueno tu planteamiento del problema. Estoy de acuerdo con que esa es la razón por la que sucede el bug. Lastimosamente probé el useLayoutEffect y no me funciono. Sigo buscando una solución pues en mi caso particular nunca se me muestra el reproductor. Me quedo fijo en el 404,

        Daniel Alejandro Alvarez Garcia

        Daniel Alejandro Alvarez Garcia

        student•
        hace 6 años

        Lo que dices esta bien pero el punto donde quieres llegar no esta bien planteado,el problema va mas allá de los estados es la tardanza del connect en hacer su funcion sin embargo en los aportes han dado soluciones viables y mas logicos.Sin embargo gracias por tu aporte del uso del useEffect

      Jaime Gabriel González Célleri

      Jaime Gabriel González Célleri

      student•
      hace 6 años

      Una solución podría ser tratar los 2 eventos por separado: cargar video y video no encontrado:

      import React, { useEffect, useState } from 'react' import { connect } from 'react-redux' import { getVideoSource } from '../actions' import NotFound from './NotFound' import '../assets/styles/components/Player.scss' const Player = props => { const { id } = props.match.params const [ loading, setLoading ] = useState(true) const hasPlaying = Object.keys(props.playing).length > 0 useEffect(() => { props.getVideoSource(id) setLoading(false) }, []) if (loading) return <h2>Cargando video...</h2> return hasPlaying ? ( <div className="player"> <video controls autoPlay> <source src={props.playing.source} type="video/mp4" /> </video> <div className="Player-back"> <button type="button" onClick={() => props.history.goBack()}> Regresar </button> </div> </div> ) : <NotFound /> } const mapStateToProps = state => ( { playing: state.playing } ) const mapDispatchToProps = { getVideoSource, } export default connect(mapStateToProps, mapDispatchToProps)(Player)
        Sandra Mishale Niño Arbelaez

        Sandra Mishale Niño Arbelaez

        student•
        hace 6 años

        Me gustó tu solución. Gracias.

        Manuel Alejandro Aguilar Téllez Girón

        Manuel Alejandro Aguilar Téllez Girón

        student•
        hace 6 años

        Elegante y eficaz. Felicidades y muchas gracias por tu aporte, no tenia ni idea xD

      Daniel Hernández

      Daniel Hernández

      student•
      hace 6 años

      con ECMA script 6 podemos parsear strings a numeros anteponiendo el signo +, para este caso seria: item.id === +action.payload

        Jose Anibal Garcia Giraldo

        Jose Anibal Garcia Giraldo

        student•
        hace 5 años

        Excelente aporte bro, gracias super útil! :D

      John Alexander Diaz Astudillo

      John Alexander Diaz Astudillo

      student•
      hace 6 años

      Pensé que algo estaba mal, puesto que siempre me reproducía el mismo video

      FacePalm

        Markoz Peña Mendez

        Markoz Peña Mendez

        student•
        hace 6 años

        Same :(

      Alexis Alberto Texis Auza

      Alexis Alberto Texis Auza

      student•
      hace 6 años

      Hola yo hago lo siguiente :

      -Dejo en null el atributo playing para ser mucho mas exacto en que no se ha cargado absolutamente nada. -La idea es que una vez que en el REDUCER se intente buscar el video,tendra como valor un objeto con o sin atributos. En el momento que tenga un valor(objeto) lo considero que ya se ha cargado el video y ahora lo que hago es que si esta vacio, quieres decir que no se encontro,y si es todo lo contrario retorno el componente ya que si se habra encontrado.

      const initialState = { playing : null, ... }

      En el componente :

      const media = ({id,playing,setPlaying}) => { useEffect(() =>{ setPlaying(id) },[]) const render = () => { if(!playing) return <h3>cargando...</h3> if(!Object.keys(playing).length) return <h3>No existe el video</h3> return ( <div className='video-player'> <video src={playing.source} controls autoPlay /> </div> ) } }
        Enrique Alexis Lopez Araujo

        Enrique Alexis Lopez Araujo

        student•
        hace 6 años

        Trate de implementarlo pero no logro saber donde devuelves render podrias ayudarme para saber como retornar correctamente el componente?

        Alexis Alberto Texis Auza

        Alexis Alberto Texis Auza

        student•
        hace 6 años

        Hola,lo haces en el metodo return,ejecutando la función.

        const MiComponente = () => { const render() => { ...codigo } //Si solo vas a retorna el video player,solo ejecuta la funcion return render() //Si tienes una layout harias esto. return ( <MiLayoutContainer> { render() } <MiComponente/> <MiComponente/> <Mi/LayoutContainer> ) }
      Jose Colmenares

      Jose Colmenares

      student•
      hace 6 años

      Esta es la clase que mas me ha costado del curso :/

      Pablo Martino

      Pablo Martino

      student•
      hace 5 años

      a mi no me reproducía el video. Parece que la URL es prvada y no permite visualizar.

      Podéis sino usar algún video de stock y sustituirlo en el index.js principal.

      os dejo uno si alguien necesita https://static.videezy.com/system/resources/previews/000/044/479/original/banana.mp4

      IVAN DARIO CHIPATECUA CABEZAS

      IVAN DARIO CHIPATECUA CABEZAS

      student•
      hace 6 años

      Yo utilice useState.

      <code> import React, { useState, useEffect } from 'react'; import { connect } from 'react-redux'; import { Redirect } from 'react-router-dom'; import { getVideoSource } from '../actions'; import '../assets/styles/components/Player.scss'; const Player = (props) => { const { id } = props.match.params; const [loading, changeLoading] = useState(true); const hasPlaying = Object.keys(props.playing).length > 0; useEffect(() => { props.getVideoSource(id); changeLoading(false); }, []); return loading ? (<h1>Loading...</h1>) : hasPlaying ? ( <div className='Player'> <video controls autoPlay> <source src={props.playing.source} type='video/mp4' /> </video> <div className='Player-back'> <button type='button' onClick={() => props.history.goBack()}> Regresar </button> </div> </div> ) : <Redirect to='/404' />; }; const mapStateToProps = (state) => { return { playing: state.playing, }; }; const mapDispatchToProps = { getVideoSource, }; export default connect(mapStateToProps, mapDispatchToProps)(Player); </code>
      Javier Romero

      Javier Romero

      student•
      hace 5 años

      una pregunta compañeros tengo que poner un video o algo asi porque no me sale nada 😅😅

        Alex Camacho

        Alex Camacho

        teacher•
        hace 5 años

        Sí, debes de añadir un video para probar el reproductor x)

        Javier Romero

        Javier Romero

        student•
        hace 5 años

        hola en que parte del código pongo ese video 😅

      Carlos Rafael Padilla Ramirez

      Carlos Rafael Padilla Ramirez

      student•
      hace 5 años

      En este bloque el profesor puso original en lugar de originals por si tienen el mismo problema que yo.

      case 'GET_VIDEO_SOURCE': return { ...state, playing: state.trends.find((item) => item.id === Number(action.payload)) || state.originals.find((item) => item.id === Number(action.payload)) || [], };```
      Gaspar Dolcemascolo

      Gaspar Dolcemascolo

      student•
      hace 5 años

      Los videos ya no están disponibles verdad? Me sale esto en consola, aclaro de que el playing me retorna todo el obj con source incluido.

      GEThttps://mdstrm.com/video/58333e214ad055d208427db5.mp4 La carga HTTP ha fallado con el estado 401. Ha fallado la carga del recurso de medios https://mdstrm.com/video/58333e214ad055d208427db5.mp4. 8 Ha fallado la carga de todos los recursos candidatos. Carga de medios pausada.
        Edwin Olaff Cuba Davila

        Edwin Olaff Cuba Davila

        student•
        hace 5 años

        Hola @gasparnd, ya no estan disponibles los videos, ahora son privados. Te recomiendo que cambiar la url del source de los video por esta "https://" "commondatastoragegoogleapis.con/gtv-videos-bucket/sample/BigBuckBunny.mp4" para que al menos puedas probar su funcionalidad.

        Gaspar Dolcemascolo

        Gaspar Dolcemascolo

        student•
        hace 5 años

        Gracias =D

      Andres David Sanchez

      Andres David Sanchez

      student•
      hace 5 años

      No entendi porque utilizo useEffect para llamar el reducer! Alguien puede explicarmee? :(

        andrés eduardo betancourt bescanza

        andrés eduardo betancourt bescanza

        student•
        hace 5 años

        Recuerda que useEffect se ejecuta de primero, asi al hacer click en el componente este busca el id que se utilizara para renderizar el video

      Sebastián Buitrago

      Sebastián Buitrago

      student•
      hace 5 años

      Hay alguna diferencia entre usar "react-router" y "react-router-dom" al momento de importar un archivo ya que mi auto import me pone los archivos asi

      import { Redirect } from "react-router"
      Platzi Nauta

      Platzi Nauta

      student•
      hace 4 años

      Que tal! Les comparto el initialState actualizado con nuevos sources para los videos, ya que los que venían originalmente no se podían acceder.

      https://gist.github.com/Fredyspt/087cc10ad1ac0513eb2683cb684b5a15

        Franklin Gerardo Pimentel Hernández

        Franklin Gerardo Pimentel Hernández

        student•
        hace 4 años

        Woow, muchas gracias. Esto es lo que me faltaba :3

      Andrés Campuzano Garzón

      Andrés Campuzano Garzón

      student•
      hace 6 años

      🦄 Acá el código trabajado hasta el momento: https://github.com/AndresCampuzano/React-Router-and-Redux/commits/master

        César Palma

        César Palma

        student•
        hace 4 años

        me gusta tu repositorio con commits por clase, ayuda a revisar algun cambio faltante

    Escuelas

    • Desarrollo Web
      • Fundamentos del Desarrollo Web Profesional
      • Diseño y Desarrollo Frontend
      • Desarrollo Frontend con JavaScript
      • Desarrollo Frontend con Vue.js
      • Desarrollo Frontend con Angular
      • Desarrollo Frontend con React.js
      • Desarrollo Backend con Node.js
      • Desarrollo Backend con Python
      • Desarrollo Backend con Java
      • Desarrollo Backend con PHP
      • Desarrollo Backend con Ruby
      • Bases de Datos para Web
      • Seguridad Web & API
      • Testing Automatizado y QA para Web
      • Arquitecturas Web Modernas y Escalabilidad
      • DevOps y Cloud para Desarrolladores Web
    • English Academy
      • Inglés Básico A1
      • Inglés Básico A2
      • Inglés Intermedio B1
      • Inglés Intermedio Alto B2
      • Inglés Avanzado C1
      • Inglés para Propósitos Específicos
      • Inglés de Negocios
    • Marketing Digital
      • Fundamentos de Marketing Digital
      • Marketing de Contenidos y Redacción Persuasiva
      • SEO y Posicionamiento Web
      • Social Media Marketing y Community Management
      • Publicidad Digital y Paid Media
      • Analítica Digital y Optimización (CRO)
      • Estrategia de Marketing y Growth
      • Marketing de Marca y Comunicación Estratégica
      • Marketing para E-commerce
      • Marketing B2B
      • Inteligencia Artificial Aplicada al Marketing
      • Automatización del Marketing
      • Marca Personal y Marketing Freelance
      • Ventas y Experiencia del Cliente
      • Creación de Contenido para Redes Sociales
    • Inteligencia Artificial y Data Science
      • Fundamentos de Data Science y AI
      • Análisis y Visualización de Datos
      • Machine Learning y Deep Learning
      • Data Engineer
      • Inteligencia Artificial para la Productividad
      • Desarrollo de Aplicaciones con IA
      • AI Software Engineer
    • Ciberseguridad
      • Fundamentos de Ciberseguridad
      • Hacking Ético y Pentesting (Red Team)
      • Análisis de Malware e Ingeniería Forense
      • Seguridad Defensiva y Cumplimiento (Blue Team)
      • Ciberseguridad Estratégica
    • Liderazgo y Habilidades Blandas
      • Fundamentos de Habilidades Profesionales
      • Liderazgo y Gestión de Equipos
      • Comunicación Avanzada y Oratoria
      • Negociación y Resolución de Conflictos
      • Inteligencia Emocional y Autogestión
      • Productividad y Herramientas Digitales
      • Gestión de Proyectos y Metodologías Ágiles
      • Desarrollo de Carrera y Marca Personal
      • Diversidad, Inclusión y Entorno Laboral Saludable
      • Filosofía y Estrategia para Líderes
    • Diseño de Producto y UX
      • Fundamentos de Diseño UX/UI
      • Investigación de Usuarios (UX Research)
      • Arquitectura de Información y Usabilidad
      • Diseño de Interfaces y Prototipado (UI Design)
      • Sistemas de Diseño y DesignOps
      • Redacción UX (UX Writing)
      • Creatividad e Innovación en Diseño
      • Diseño Accesible e Inclusivo
      • Diseño Asistido por Inteligencia Artificial
      • Gestión de Producto y Liderazgo en Diseño
      • Diseño de Interacciones Emergentes (VUI/VR)
      • Desarrollo Web para Diseñadores
      • Diseño y Prototipado No-Code
    • Contenido Audiovisual
      • Fundamentos de Producción Audiovisual
      • Producción de Video para Plataformas Digitales
      • Producción de Audio y Podcast
      • Fotografía y Diseño Gráfico para Contenido Digital
      • Motion Graphics y Animación
      • Contenido Interactivo y Realidad Aumentada
      • Estrategia, Marketing y Monetización de Contenidos
    • Desarrollo Móvil
      • Fundamentos de Desarrollo Móvil
      • Desarrollo Nativo Android con Kotlin
      • Desarrollo Nativo iOS con Swift
      • Desarrollo Multiplataforma con React Native
      • Desarrollo Multiplataforma con Flutter
      • Arquitectura y Patrones de Diseño Móvil
      • Integración de APIs y Persistencia Móvil
      • Testing y Despliegue en Móvil
      • Diseño UX/UI para Móviles
    • Diseño Gráfico y Arte Digital
      • Fundamentos del Diseño Gráfico y Digital
      • Diseño de Identidad Visual y Branding
      • Ilustración Digital y Arte Conceptual
      • Diseño Editorial y de Empaques
      • Motion Graphics y Animación 3D
      • Diseño Gráfico Asistido por Inteligencia Artificial
      • Creatividad e Innovación en Diseño
    • Programación
      • Fundamentos de Programación e Ingeniería de Software
      • Herramientas de IA para el trabajo
      • Matemáticas para Programación
      • Programación con Python
      • Programación con JavaScript
      • Programación con TypeScript
      • Programación Orientada a Objetos con Java
      • Desarrollo con C# y .NET
      • Programación con PHP
      • Programación con Go y Rust
      • Programación Móvil con Swift y Kotlin
      • Programación con C y C++
      • Administración Básica de Servidores Linux
    • Negocios
      • Fundamentos de Negocios y Emprendimiento
      • Estrategia y Crecimiento Empresarial
      • Finanzas Personales y Corporativas
      • Inversión en Mercados Financieros
      • Ventas, CRM y Experiencia del Cliente
      • Operaciones, Logística y E-commerce
      • Gestión de Proyectos y Metodologías Ágiles
      • Aspectos Legales y Cumplimiento
      • Habilidades Directivas y Crecimiento Profesional
      • Diversidad e Inclusión en el Entorno Laboral
      • Herramientas Digitales y Automatización para Negocios
    • Blockchain y Web3
      • Fundamentos de Blockchain y Web3
      • Desarrollo de Smart Contracts y dApps
      • Finanzas Descentralizadas (DeFi)
      • NFTs y Economía de Creadores
      • Seguridad Blockchain
      • Ecosistemas Blockchain Alternativos (No-EVM)
      • Producto, Marketing y Legal en Web3
    • Recursos Humanos
      • Fundamentos y Cultura Organizacional en RRHH
      • Atracción y Selección de Talento
      • Cultura y Employee Experience
      • Gestión y Desarrollo de Talento
      • Desarrollo y Evaluación de Liderazgo
      • Diversidad, Equidad e Inclusión
      • AI y Automatización en Recursos Humanos
      • Tecnología y Automatización en RRHH
    • Finanzas e Inversiones
      • Fundamentos de Finanzas Personales y Corporativas
      • Análisis y Valoración Financiera
      • Inversión y Mercados de Capitales
      • Finanzas Descentralizadas (DeFi) y Criptoactivos
      • Finanzas y Estrategia para Startups
      • Inteligencia Artificial Aplicada a Finanzas
      • Domina Excel
      • Financial Analyst
      • Conseguir trabajo en Finanzas e Inversiones
    • Startups
      • Fundamentos y Validación de Ideas
      • Estrategia de Negocio y Product-Market Fit
      • Desarrollo de Producto y Operaciones Lean
      • Finanzas, Legal y Fundraising
      • Marketing, Ventas y Growth para Startups
      • Cultura, Talento y Liderazgo
      • Finanzas y Operaciones en Ecommerce
      • Startups Web3 y Blockchain
      • Startups con Impacto Social
      • Expansión y Ecosistema Startup
    • Cloud Computing y DevOps
      • Fundamentos de Cloud y DevOps
      • Administración de Servidores Linux
      • Contenerización y Orquestación
      • Infraestructura como Código (IaC) y CI/CD
      • Amazon Web Services
      • Microsoft Azure
      • Serverless y Observabilidad
      • Certificaciones Cloud (Preparación)
      • Plataforma Cloud GCP

    Platzi y comunidad

    • Platzi Business
    • Live Classes
    • Lanzamientos
    • Executive Program
    • Trabaja con nosotros
    • Podcast

    Recursos

    • Manual de Marca

    Soporte

    • Preguntas Frecuentes
    • Contáctanos

    Legal

    • Términos y Condiciones
    • Privacidad
    • Tyc promociones
    Reconocimientos
    Reconocimientos
    Logo reconocimientoTop 40 Mejores EdTech del mundo · 2024
    Logo reconocimientoPrimera Startup Latina admitida en YC · 2014
    Logo reconocimientoPrimera Startup EdTech · 2018
    Logo reconocimientoCEO Ganador Medalla por la Educación T4 & HP · 2024
    Logo reconocimientoCEO Mejor Emprendedor del año · 2024
    De LATAM conpara el mundo
    YoutubeInstagramLinkedInTikTokFacebookX (Twitter)Threads