Bienvenido al curso

1

Conoce a tu profesor y todo lo que aprenderás sobre Redux

2

¿Qué conocimientos me recomiendan para tomar este curso?

Repaso React

3

¿Qué es React y cómo funciona?

4

Preparando nuestro entorno de trabajo

5

Creación de la app con React

6

Agregando funciones a la app con React

7

Stateful vs Stateless

8

Ciclo de vida de React

9

Manejando promesas

10

React Router DOM

Introducción a Redux

11

¿Qúe es Redux, cuándo usarlo y por qué?

Fases de Redux

12

Introducción: las fases de Redux

13

Store

14

Reducers

15

Conexión a un componente

16

Action Creators

17

Redux Thunk

18

Explicación teórica: ciclo completo de Redux

19

Práctica: ciclo completo de Redux

Fases Extra

20

Archivos Types

21

Try Catch

22

Escenarios asíncronos

23

Componente Spinner

24

Componente Fatal

25

Tabla como componente

Compartir información en Redux

26

Introducción Compartir información en Redux

27

Parámetros por URL

28

Compartir Reducer

29

Múltiples Reducers

30

Llamando a múltiples reducers en una acción

31

Uso del estado en la acción

32

Evitar segundas búsquedas

33

Inmutabilidad

34

Evitar sobrescritura

35

Validación compuesta

36

Validación de errores

37

Modificando respuesta de url

38

Estado con interacción

39

Mostrar componentes dinámicamente

40

Llamadas asincronas dinámicas

41

Props por herencia vs estado

42

Estado compartido

Métodos HTTP

43

Introducción a métodos HTTP

44

Nuevo ciclo Redux

45

Normalizar datos

46

Mapear Objetos

47

Componente para agregar tarea

48

Manejar inputs con Reducer

49

POST

50

Deshabilitando botón

51

Redireccionar

52

Reutilizar componentes

53

PUT

54

DELETE

55

Últimos detalles

Conclusión

56

Conocimientos adquiridos

57

Qué hacer a continuación

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Curso de Redux por Bedu

Curso de Redux por Bedu

Rodolfo Saldivar

Rodolfo Saldivar

Validación compuesta

35/57
Recursos

Aportes 34

Preguntas 1

Ordenar por:

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

Cómo que le gusta el spaghetti a éste mastero

Esto se puso muy caótico. Es muy bueno el curso, pero para los que vieron el curso de react.js, apliquen componentes en diferentes archivos y entenderán mucho mejor.

No me imagino como sera el manejo en una app más grande, solo hemos hecho dos paginas y el código es infernal.

demasiado codigo spaghetti

Considero que hacer validaciones con el .length puede ocasionar problemas en el futuro ya que en cierto momento puede que no hayan registros en la base de datos. Se podría poner un type nuevo que indique si los usuarios o posts ya fueron consultados, por ejemplo POSTS_FETCHED y USERS_FETCHED

Poco Redux y mucho javascript normalito y encontrandolé la vuelta a todo

Hola Devs:
Unanse conmigo todos aqui: 😭
-Por esa razon desde el principio del proyecto me hice la tarea de hacer todo desde cero por mi cuenta y no seguir tal y cual lo hace el profesor, al principio lo hacia como reto personal hacer algo por mi cuenta, pero a la larga me di cuenta de que tome una maravillosa decision, para los que deseen ver mi codigo (por cierto creo que es mas limpio y moderno), pueden checar mi repositorio: Click Aqui 😃

che, este curso está chequeado producción? jejeje Me vengo perdiendo como un campeón todo este modulo!

El problema es que principalmente esta realizando codigo imperativo y no declarativo, es necesario refactorizar y no tener todo un paso a paso imperativo

Desde que el profesor comenzó a utilizar el index de la data como key para todas las demás operaciones deje de seguirle los ejemplos referentes a como traer publicaciones/usuarios, y ya por este punto se enredó mucho explicando y creo que para el que no este familiarizado se le debe hacer muy confusa esta parte. Ya que parece que comenzó a preparar un spaghetti. Muy bien el conocimiento general que otorga pero debe mejorar la manera de plantear los casos ya que se cumple el objetivo pero pero de una manera muy confusa.

me ha ido gustando mucho las clases pero siento que en la parte de los if debe haber alguna forma de hacerlo mas practico y consumir menos lineas de código.

Yo sigo sin entender de la misa la mitad…

Siento que en varias partes del curso hizo cosas muy poco prácticas pero sin duda esta es la más clara que las validaciones se puede hacer mejor.

El profesor es muy bueno para entender su código y no perderse en su proceso, yo hace un par de clases mi perdi😥. Pero hay sigo intentandole comprender el tema.

Si alguien se quiere ahorrar css el elemento <hr/> dibuja una raya en HTML 😄

En cuanto a las críticas de ‘códigio espaguetti’ sólo comentaré que en el mundo profesional hay muchísimas aplicaciones con ésta arquitectura, como recomendación NO LO ECHEN EN SACO ROTO

Esta da pereza seguir llevando este curso

Explicación del motivo por el cual no des-estructuramos el reducer en el ComponentDidMount

Excelente clase. 🙂

Conclusión: Creamos una función llamada ponerPublicaciones() que valida los estados de publicaciones (error y cargando) y si todo sale bien ya tengo las publicaciones y de ese usuario destructuro publicaciones key (donde están las publicaciones de este usuario) y retorno todas las publicaciones que están en esa casilla del arreglo con un .map

tanto lió para mostrar las publicaciones de un usuario pero igual excelente clase…

Excelente!
Faltaría validar la existencia de publicaciones[publicaciones_key] con un

if (!publicaciones[publicaciones_key]) return;

después del const donde destructuramos publicaciones_key.
Sino da error al seleccionar otro usuario.

La sección de archivos no corresponde al mismo estado del proyecto que la clase que se presenta.

Al final no sé si no puse atención pero no había quitado el { this.props.match.params.key } y pues obviamente no estaba llamado la función {this.ponerUsuario()} entonces claramente solo me aparecía el body ni el title.

import React from "react";
import { connect } from "react-redux";

import "./styles/Publications.css";
import * as UsersAction from "../actions/UsersAction";
import * as PublicationsAction from "../actions/PublicationsAction";
import Loading from "../components/Loading";
import Error from "../components/Error";

class Publications extends React.Component {
  async componentDidMount() {
    const {
      UsersReducer: { Data },
      Add_AllsUsers,
      Add_AllsPublicationsByUser,
      match: {
        params: { Id }
      }
    } = this.props;

    if (!Data.length) {
      await Add_AllsUsers();
    }

    if (this.props.UsersReducer.Error) return;

    const UserIndex = this.props.UsersReducer.Data.findIndex(user => {
      return user.id === parseInt(Id);
    });

    if (!("PublicationsIndex" in this.props.UsersReducer.Data[UserIndex])) {
      await Add_AllsPublicationsByUser(Id);
    }
  }

  publications = () => {
    const {
      UsersReducer: { Data },
      PublicationsReducer: { Publications },
      match: {
        params: { Id }
      }
    } = this.props;

    const UserIndex = Data.findIndex(user => {
      return user.id === parseInt(Id);
    });

    const { PublicationsIndex } = Data[UserIndex];

    return Publications[PublicationsIndex].map(element => {
      return (
        <div className="Title">
          <h2>{element.title} </h2>
          <p>{element.body} </p>
        </div>
      );
    });
  };

  render() {
    const {
      UsersReducer,
      PublicationsReducer,
      UsersReducer: { Data },
      PublicationsReducer: { Publications },
      match: {
        params: { Id }
      }
    } = this.props;

    if (UsersReducer.Error || PublicationsReducer.Error) {
      return <Error error={UsersReducer.Error || PublicationsReducer.Error} />;
    }

    const UserIndex = Data.findIndex(user => {
      return user.id === parseInt(Id);
    });

    if (
      UsersReducer.Loading ||
      PublicationsReducer.Loading ||
      !Publications.length ||
      !Data.length ||
      !("PublicationsIndex" in Data[UserIndex])
    ) {
      return <Loading />;
    }

    const User = Data.find(user => {
      return user.id === parseInt(Id);
    });

    return (
      <div className="margin">
        <h1>Publications´s {User.name}</h1>
        {this.publications()}
      </div>
    );
  }
}

const mapStateToProps = ({ UsersReducer, PublicationsReducer }) => {
  return { UsersReducer, PublicationsReducer };
};

const mapDispatchToProps = {
  ...UsersAction,
  ...PublicationsAction
};

export default connect(mapStateToProps, mapDispatchToProps)(Publications);

Logre traer las publicaciones ! sin embargo creo que la validacion de: cuando no hay usuarios no hacer nada debi retirarla porque si no la funcion useEffect parece que no se ejecuta completa,

Es como que las publicaciones cargan despues del tercer render.
Quisiera saber si a alguien mas le paso ? alguien mas esta usando componentes funcionales ?

import * as postsActions from '../../Redux/Actions/postsActionsCreator';
import * as userActions from '../../Redux/Actions/usersActionsCreator';
import {useParams} from "react-router-dom";
import React, {useEffect} from 'react'
import {connect} from 'react-redux';

import Loading from '../../Pages/Loading';
import Error from '../../Pages/Error';

function Posts(props) {
    let params = useParams();

    // eslint-disable-next-line react-hooks/exhaustive-deps
    useEffect( async()=> {
        // Este async es para que llama primero a los users y despues los posts
        if (!props.usersReducer.users.length) {
           await props.fetchUsers();
        }

        // Esta parte evita que se cargen los posts, depronto por culpa del effect
        // Esto evita errores, cuando aun no hay usuarios cargados
        // if (!props.usersReducer.error) {
        //     return
        //  }

        // Las post no deben traerse si ya existe publicaciones key, las post de un mismo usuario no deben cargarse de nuevo al cambiar de pantalla y volver a consultar el mismo usuario, por eso vamos a validar:
        if (!('publicaciones_key' in props.usersReducer.users[params.key])) {
            props.getUserPosts(params.key);
        }

    },[] );

    const nombreUsuario = () => {
        if (props.usersReducer.error) {
            return <Error error={props.usersReducer.error}/>
        }

        if (!props.usersReducer.users.length || props.usersReducer.loading) {
            return <Loading/>
        }

        return (
            <>
                <h1>Post del usuario key {params.key}</h1>
                <h2>ID: {props.usersReducer.users[params.key].id}</h2>
                <h2>Name: {props.usersReducer.users[params.key].name}</h2>
            </>
        )
    };

    const publishPosts = () => {

        // Validar que la informacion del usuario sea correcta
        if (!props.usersReducer.users.length) return (
            <h3>NO hay usuarios</h3>
        );

        // No hacemos nada, esta validacion ya se esta manejando dentro de nombreUsuario()
        if (props.usersReducer.error) return;

        if (props.postsReducer.cargando) {
            return <Loading/>
        }

        if (props.postsReducer.error) {
            return <Error error={props.postsReducer.error}/>
        }

        if (!props.postsReducer.posts.length) return;

        if (!('publicaciones_key' in props.usersReducer.users[params.key])) return;

        console.log("🚀 ~ usersReducer", props.usersReducer)
        console.log("🚀 ~ postsReducer", props.postsReducer)

        return props.postsReducer.posts[params.key].map(
            (post) => (
                <>
                    <hr/>
                    <h2>{post.title}</h2>
                    <div>{post.body}</div>
                </>
            )
        );

    };

    return (
        <>
            <div>{nombreUsuario()}</div>
            <div>{publishPosts()}</div>
        </>

  )
}

// Asi conectamos multiples reducers:
// destructuramos los reducers, ellos se combinaron en el index.js de la carpeta reducers
const mapStateToProps = ({usersReducer, postsReducer}) => {
    return {usersReducer, postsReducer};
};

// Asi se conectan multiples acciones al componente
const mapDispatchToProps = {
    ...userActions,
    ...postsActions
};

export default connect(mapStateToProps, mapDispatchToProps)(Posts);

Aquí es donde se forjan los programadores mas recios jaja

Un sistema de validaciones, que aunque parece extenso, es realmente últil. La información es clara.
Sin embargo el inconveniente que Redux tiene en este punto es visible: La cantidad de boilerplate y carpetas y archivos, hace ver demasiado código y puede ser confuso. Es totalmente innecesario visto desde el punto de vista de entendimiento. Pero es esto, lo que en un futuro permite a mi código ser escalable. No muy legible, pero con un tiempo dedicado se entiende todo.

No entiendo nada jajajajaja

no se pero me encanta su forma de programar jaja

Es muy confuso el curso o talvez sea el código muy desordenado jeje… pero ahí vamos poquito a poquito

Muy buena clase

Excelente

Justo así me imaginaba que era todo el flujo de la información, me imagino que se vuelve más complejo cuando los componentes como el header o pequeños features que se escriben alrededor como mensajes o notificaciones tienen que cargar los cuales no son propios de la página tienen que cambiar dinámicamente dependiendo las respuestas que traigan la API, por eso es importante echar mano de herramientas como Postman para ver como se comporta la API o Redux Dev Tools para ir viendo como se comporta el flujo de información. Ahora imagínense un facebook o un Youtube que tiene que cargar primero al usuario/video, a los comentarios después, a las sugerencias. Este curso está demasiado completo y complejo.

Hay que repasar el código para entenderlo mejor