CursosEmpresasBlogLiveConfPrecios

Finalizando reducers y eliminar favoritos

Clase 14 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

    Viendo ahora
  • 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

    13:50 min
  • 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
    • Daniel Pereira Perez

      Daniel Pereira Perez

      student•
      hace 6 años

      En lo personal no recomiendo pasar el nombre de las acciones como texto plano, es muy posible crear typos.

      Deberían utilizar un objeto intermediario que maneje cada acción, en mi caso queda algo así: Actions

      Reducers

        Juan Castro

        Juan Castro

        teacher•
        hace 6 años

        Sip. Son los actionTypes. Son una muy buena práctica para depurar y evitar typos lo más de tontos.

        El profesor lo explica muy bien en esta clase: https://platzi.com/clases/1613-redux/20655-archivos-typ-9/.

        leonardo Oteca

        leonardo Oteca

        student•
        hace 6 años

        Iniciando la clase vi este comentario y dije Hey que buena idea de utilizar actionTypes pero creo que no los voy a usar por ahora al finalizar tenía un typo, adivinen de qué se trataba!

      Carlos Hernández Méndez

      Carlos Hernández Méndez

      student•
      hace 6 años

      Recomendación: Ulilizar constantes en Redux. Es recomendable usar constantes en redux, por ejemplo, crear un archivo que se llame "actionTypes.js", y dentro colocar lo siguiente:

      export const SET_FAVORITE = 'SET_FAVORITE' export const DELETE_FAVORITE = 'DELETE_FAVORITE'

      Estas constantes las importaremos en los actions y en los reducers.

      ¿Con qué fin se usan estas constantes? Muchos no le encuentran sentido porque el valor tiene el mismo nombre que la constante, pero los beneficios son los siguientes.

      • Ayuda a mantener una consistencia y evita los errores al escribir código, ya que si escribes Strings en las actions y en los reducers puede que en una de esas veces te equivoques.
      • Algunas veces el usuario desea ver qué actions existen antes de trabajar en alguna. Si trabajas en un equipo puede que alguien la haya implementado. Tener todas las actions como constantes en un archivo te facilitará esa búsqueda.
      • La lista de_ action types_ que fueron añadidas, eliminadas o actualizadas en un _Pull Request _ayuda a todo el equipo a visualizar rápidamente qué cambios se están haciendo en la funcionalidad.
      • Si cometes un error (typo) cuando importas tus constantes, obtendrás undefined cuando intentes ejecutar tu código. Es más fácil encontrar este error de variable que intentando descifrar por qué no pasa nada cuando ejecutas tu action.

      Espero que les haya servido de algo. No es algo que yo me haya inventado, muchos manejan esa escructura. Si gustan, aquí les dejo más información:

        Rodrigo Rodriguez

        Rodrigo Rodriguez

        student•
        hace 5 años

        esta buena tu idea, ademas de que hardcodear no es una buena practica.

      Andrés Felipe Eslava Zuluaga

      Andrés Felipe Eslava Zuluaga

      student•
      hace 5 años

      Ha sido doloroso pero reconfortante saber que he entendido. Por favor corrijanme lo que sea necesario. Es complejo entender el patrón de diseño de Flux, pues todo es archivos separados, pero tomando el tiempo de entender todo es legible. Les dejo mi comprensión, espero les aydue a quiénes no la logran de primera: .

      1. Se alimenta la aplicación por medio del Provider cuando definimos el createStore(reducer, initialState). Ésto le enviará información al componente que necesite acceder al Store.
      // index.js const initialStore = { /* ... */ } const store = createStore(reducer, initialState); ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('app'), );

      1.1. El reducer va a recibir el estado inicial que se pasa en createStore , pero también, en su función recibirá la acción que debe hacer cuando ocurra un llamado al Store. . 2. Dentro del reducer vamos a devolver el estado actualizado del Store únicamente cuando ocurra una acción, cuando se despache una acción . Dependiendo de la acción el estado del store se actualiza o se queda igual, sea agregar a favorito o crear un estado inicial al ingresar a Home, respectivamente por ejemplo.

      2.1. El payload es lo que vamos a enviarle a la acción, que recibirá el reducer, para actualizar el Store o actualizar el estado.

      // actions.js export const setFavorite = (payload) => ({ type: 'SET_FAVORITE', payload, }); export const deleteFavorite = (payload) => ({ type: 'DELETE_FAVORITE', payload, });

      2.2. Cuando el reducer recibe ese payload por medio del action, podemos hacer algo con la informació, en este caso, se actualiza la lista myList

      // reducer.js const reducer = (state, action) => { switch (action.type) { case 'SET_FAVORITE': console.log('action -> ', action); return { ...state, myList: [ ...state.myList.filter((item) => item.id !== action.payload.id), action.payload, ], }; case 'DELETE_FAVORITE': console.log('state.myList -> ', state.myList); return { ...state, myList: state.myList.filter((item) => item.id !== action.payload), }; default: return state; } }; export default reducer;

      . 3. Al tener definida la estructura del Store, del reducer y de las acciones, podemos definir funciones para manejar estas acciones directamente en el UI --> Renderizamos la información en componente Home: 3.1. Conectamos Home al Store por medio de connect():

      // Home.jsx export default connect(mapStateToProps, null)(Home);

      3.2. Definimos la información que debe traer Home desde el store, es por eso que se define ++mapStateToProps++ , pues será el argumento que trae del estado de Store la información que necesita el componente, y pasa como PROPIEDADES al mismo componente:

      // Home.jsx const mapStateToProps = (state) => { return { myList: state.myList, trends: state.trends, originals: state.originals, }; };

      3.3. Se pasan las propiedades a Home:

      // Home.jsx const Home = ({ myList, trends, originals }) => { return ( <> <Search /> { myList.length > 0 && ( <Categories title='Mi lista'> <Carousel> {myList?.map((item) => { return ( <CarouselItem key={item.id} {...item} /> ); })} </Carousel> </Categories> )} <Categories title='Originals'> <Carousel> {originals?.map((item) => { return ( <CarouselItem key={item.id} {...item} /> ); })} </Carousel> </Categories> <Categories title='Trends'> <Carousel> {trends?.map((item) => { return ( <CarouselItem key={item.id} {...item} /> ); })} </Carousel> </Categories> </> ); };
      1. Estas propiedades las recibe el componente CarouselItem y serán las que pinten una película. sea en la lista de Trends u Originals. 4.1. Para que reciba props, se debe conectar el componente al Store:
      // CarouselItem const mapDispatchToProps = { setFavorite, deleteFavorite, }; export default connect(null, mapDispatchToProps)(CarouselItem);

      4.2. El objeto mapDispatchToProps trae las ACCIONES. Se realiza puesto que en cada CarouselItem vamos a ejecutar una acción que modificará el Store -> Estas acciones también se podrán llamar por medio de los PROPS del componente. Logrando que podamos definir los manejadores de estas acciones:

      // CarouselItem.jsx const CarouselItem = (props) => { const { id, cover, title, year, contentRating, duration } = props; const handleSetFavorite = () => { props.setFavorite({ id, cover, title, year, contentRating, duration, }); }; const handleDeleteFavorite = () => { props.deleteFavorite(id); }; return ( !id ? ( <> <p>La lista está vacía</p> </> ) : ( <> <div className='Carousel--item'> <img className='Carousel--item__img' src={cover} alt={title} /> <div className='Carousel--item__details'> <p className='Carousel--item__details--title'>{title}</p> <p className='Carousel--item__details--subtitle'> {`${year} | ${contentRating} | ${duration}`} </p> <div className='Carousel--item__details--buttons'> <img src={playIcon} alt='Play' /> <img src={plusIcon} alt='Plus' onClick={handleSetFavorite} /> <img src={removeIcon} alt='Delete' onClick={handleDeleteFavorite} /> </div> </div> </div> </> ) ); }; CarouselItem.propTypes = { id: PropTypes.number, cover: PropTypes.string, title: PropTypes.string, year: PropTypes.number, contentRating: PropTypes.string, duration: PropTypes.number, };

      Renderizando cada uno de los items que existen en el Store. . 5. El render inicial hará que existan listas de Trends y Originals, pero cada uno de los CarouselItem tendrá una acción: setFavorite y deleteFavorite. Estas acciones manipulan el Store definiendo los estados para la lista de favoritos (myList).

        Ronald Maco

        Ronald Maco

        student•
        hace 5 años

        Gracias por la información.

        Rodrigo Rodriguez

        Rodrigo Rodriguez

        student•
        hace 5 años

        Wow, excelente aporte, ! lo lei completo!

      Andrés Campuzano Garzón

      Andrés Campuzano Garzón

      student•
      hace 6 años

      🦄 Acá todo el código de la clase hasta este momento: https://github.com/AndresCampuzano/React-Router-and-Redux/commit/a3a4ae8f9addc5807b5421dc30be793fed16a639

        Henry Caicedo Velasco

        Henry Caicedo Velasco

        student•
        hace 5 años

        Gracias

        Andrés Felipe Eslava Zuluaga

        Andrés Felipe Eslava Zuluaga

        student•
        hace 5 años

        gracias!

      Marco Alejandro Rodriguez Ferrer

      Marco Alejandro Rodriguez Ferrer

      student•
      hace 5 años

      Una sugerencia para que no se agregue el mismo elemento varias veces a myList puede ser:

      reducer.png
      Daniel Alejandro Contreras Suárez

      Daniel Alejandro Contreras Suárez

      student•
      hace 6 años

      Yo escribi la funcion handleDeleteFavorite de la siguiente manera:

      const handleDeleteFavorite = () =&gt; { props.deleteFavorite(id); };

      Y en el onclick de remove quedo asi:

      onClick={handleDeleteFavorite}

      Ya que estamos descomponiendo el valor id de props, no veo la razon de crear una arrow function en el evento onclick para pasarle el valor del id.

        Edgar Ocampo

        Edgar Ocampo

        student•
        hace 5 años

        Pensé lo mismo exactamente cuando lo estaba haciendo, funciona igual

        Daniel Abanto

        Daniel Abanto

        student•
        hace 5 años

        totalmente de acuerdo.

      Marco Mesén Campos

      Marco Mesén Campos

      student•
      hace 6 años

      ¿Porque ejecuta las funciones de los actions llamandolas como desde los props? es decir, porque usa: props.setFavorite, o props.DeleteFavorite

        Luis Lira

        Luis Lira

        student•
        hace 6 años

        Justo para eso sirve el mapDispatchToProps, por convención de Redux los actions deben de pasarse a los props y ser usados desde ahí.

        Aunque también se puedan importar y ejecutar directamente donde los necesitamos, las buenas prácticas indican que debemos pasarlos hacia las props.

        Marco Mesén Campos

        Marco Mesén Campos

        student•
        hace 6 años

        Gracias! Justo creo que eso es lo que no me había terminado de comprender, fui a doc de redux para terminar de comprenderlo, dejo acá el Link donde terminé de comprender como el connect() 'transforma' el componente de manera que modifica sus props

      Carlos Eduardo Santaella Guevara

      Carlos Eduardo Santaella Guevara

      student•
      hace 5 años
      <img className="carousel-item__details--img" src={removeIcon} alt="Plus Icon" onClick={() => handleDeleteFavorite(id)} />

      una pregunta, por que hay veces que se llaman las funciones en el onClick de esa manera y otras veces se omite el "() =>" ? gracias de antemano!

        Nicolás Arias González

        Nicolás Arias González

        student•
        hace 5 años

        Recuerda que cuando escribes () => estás definiendo una función. Si lo pones o lo omites dependerá de si quieres crear una función nueva en la definición o si ya tienes una función que puedes usar directamente.

        Te dejo un ejemplo de los 2 casos. Los 2 son exactamente iguales, solo que en uno definimos la función antes y en el otro la definimos en el mismo tag.

        const Ejemplo = function (id, handleLike) { const onLikeClick = () => { handleLike(id); } return ( <div> <input onChange={handleChange} /> <a onClick={() => handleLike(id)} href="#">Like<a> <a onClick={onLikeClick} href="#">Like<a> </div> ) }
      john fredy quimbaya orozco

      john fredy quimbaya orozco

      student•
      hace 6 años

      al tomar está carrera pude aprender que a cada momento podemos adquirir nuevos conocimientos... me pude sorprender de lo que se puede hacer con javascript

      Jose Daniel Molina

      Jose Daniel Molina

      student•
      hace 5 años

      Genial el uso de Redux, es complicado pero con la práctica todo se aprende

        Platzi Team

        Platzi Team

        student•
        hace 5 años

        Igualmente, aun no comprendo muy bien pero espero que al practicar pueda resolver mis dudas

        Jimmy Buriticá Londoño

        Jimmy Buriticá Londoño

        student•
        hace 5 años

        Tienes razón no es fácil, pero si es importante saberlo.

      Karen Paola Diaz Duarte

      Karen Paola Diaz Duarte

      student•
      hace 5 años

      Práctica: my prefect code.

      14.PNG

      Sebastián Rodrigo Díaz

      Sebastián Rodrigo Díaz

      student•
      hace 5 años

      Esta guía sirve para entender el manejos de los eventos en React, yo tuve esa duda, con los handlers

      https://www.w3schools.com/react/react_events.asp

        Alex Camacho

        Alex Camacho

        teacher•
        hace 5 años

        Gracias por compartir, es un recurso bastante útil :muscle:

      Enmanuel Castillo

      Enmanuel Castillo

      student•
      hace 5 años

      Hello, alguien podría explicarme esta línea completa?

      myList: state.myList.filter(items => items.id !== action.payload)

      Gracias :D

        Fernando Ropero

        Fernando Ropero

        student•
        hace 5 años

        filter() crea un nuevo array con todos los elementos que cumplan la condición implementada.

        Una vez sabiendo eso

        items => items.id !== action.payload

        hacemos que el ID del item no sea igual al que estamos buscando (para que cuando encuentre el id que queremos eliminar, no lo incluya en el nuevo array) así, agregar el nuevo al array al state, que es myList:

        David Dias

        David Dias

        student•
        hace 5 años

        Ahora entiendo un poco mas por la respuesta de Fernando pero no comprendo todavía porque la comparación se hace con action.payload. Acaso ese objeto no contiene muchos elementos? se supone que items.id es un entero y action.payload un objeto, o con la funcion map ya lo estamos iterando también al igual que items?

      Jozek Andrzej Hajduk Sánchez

      Jozek Andrzej Hajduk Sánchez

      student•
      hace 5 años

      Estuve viendo el Curso de Redux por Bedu y no lo logre terminarlo por la cantidad de vacios que estaba teniendo con respecto a algunos componentes de Redux... llevo estas pocas clases con el profesor Oscar y porfin logré sintetizar de una manera muy facil y entendible (para mi) el uso de ++mapStateToProps++ y ++mapDispatchToProps++..... Respeto y admiración total por la forma tan fácil en la que enseña el profesor ☝

      Omar Dario Melendrez

      Omar Dario Melendrez

      student•
      hace 5 años

      Espero no ser el único que con cada clase que termino se me dibuja una sonrisa!! animo chicos y chicas dentro de poco vamos a crear cosas muy interesantes!!

      Celina Alejandra Speroni

      Celina Alejandra Speroni

      student•
      hace 5 años

      Hola, tengo este error, alguien me puede ayudar, desde que agregué actions y reducers no me funcionó mas, mando imagen de actions, reducers y CarouselItem. MUCHAS GRACIAS!!!

      error.PNG
      action.PNG
      reducers.PNG

      ++Este es CarouselItem++ import React from 'react'; import { connect } from 'react-redux'; import PropTypes from 'prop-types'; import { setFavorite, deleteFavorite } from '../actions'; import '../assets/styles/components/CarouselItem.scss';

      import playIcon from '../assets/static/play-icon.png'; import plusIcon from '../assets/static/plus-icon.png'; import removeIcon from '../assets/static/icons8-delete-64.png';

      const CarouselItem = (props) => { const { id, cover, title, year, contentRating, duration } = props; const handleSetFavorite = () => { props.setFavorite({ id, cover, title, year, contentRating, duration }) } const handleDeleteFavorite = (itemId) => { props.deleteFavorite(itemId) } return ( <div className="carousel-item"> <img className="carousel-item__img" src={cover} alt={title} /> <div className="carousel-item__details"> <div> <img className="carousel-item__details--img" src={playIcon} alt="Play Icon" /> <img className="carousel-item__details--img" src={plusIcon} alt="Plus Icon" onClik={handleSetFavorite} /> <img className="carousel-item__details--img" src={removeIcon} alt="Remove Icon" onClick={() => handleDeleteFavorite(id)} /> </div> <p className="carousel-item__details--title">{title}</p> <p className="carousel-item__details--subtitle"> {${year} ${contentRating} ${duration}} </p> </div> </div> ) };

      CarouselItem.propTypes = { id: PropTypes.number, cover: PropTypes.string, title: PropTypes.string, year: PropTypes.number, contentRating: PropTypes.string, duration: PropTypes.number, }

      const mapDispatchToProps = { setFavorite, deleteFavorite, }

        Edgar Lopez Arroyo

        Edgar Lopez Arroyo

        student•
        hace 5 años

        Hola @Celina75!

        De acurdo a lo que dice el error es que no reconoce el evento "onClik" y es por que no lo estas escribiendo bien, deberia ser "onClick", cambialo y prueba de nuevo.

        Espero te sirva!!

        Celina Alejandra Speroni

        Celina Alejandra Speroni

        student•
        hace 5 años

        Sí, muchas gracias @DevEdgar, era ese el error, muchas gracias por la devolución

      Henry Fehrmann

      Henry Fehrmann

      student•
      hace 5 años

      ¿Cuando uno hace f5 en el navegador, todo se pierde?

        Ismael Torres

        Ismael Torres

        student•
        hace 5 años

        Si es un formulario si, si quieres que los datos perduren necesitas crear un método que guarde los cambios temporalmente en el storage del navegador y los cargue cuando la página se cargue.

        Henry Fehrmann

        Henry Fehrmann

        student•
        hace 5 años

        Muchas gracias, otra consulta que tengo es si tengo un backend podría tener una forma de preguntar con alguna función si hizo f5, por ejemplo una función que consuma el localstorage algún email que guarde antes y si hace f5 teniendo el email podría volve a consumir y volver a rellenar los datos.

      Andres Caro

      Andres Caro

      student•
      hace 5 años

      Para los amantes de los iconos comparto

      • https://fontawesome.com/
      Laura Camila Pregonero

      Laura Camila Pregonero

      student•
      hace 5 años

      Good Class!!!

      ........................... ............................
      Tomas Goldenberg

      Tomas Goldenberg

      student•
      hace 6 años

      como podriamos hacer para que el remove-icon solo se muestre en myList y no en todas las secciones?

        Marco Mesén Campos

        Marco Mesén Campos

        student•
        hace 6 años

        Si puedes hacerlo con un if, dentro de la function haces algo así

        if(isMyList){ <img 'atributos del tipo que necesitas' /> } else { <img 'otros atributos' /> }

        Y recibes el 'isMyList' desde los props

    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