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

Tabla como componente

25/57
Recursos

Aportes 31

Preguntas 7

Ordenar por:

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

Yo lo hice un poquito diferente鈥 Separ茅 lo m谩s que pude las responsabilidades, dejando en el index el manejo de datos, y el resto simples Functional Components鈥

Este es mi Users/index.js

import React, { Component, Fragment } from 'react';
import { connect } from 'react-redux';

import * as usersActions from '../../actions/usersActions';

import Spinner from '../General/Spinner';
import Fatal from '../General/Fatal';
import Table from './Table';

class Users extends Component {
  componentDidMount() {
    this.props.getAllUsers();
  }

  putContent = () => {
    if ( this.props.loading ) {
      return <Spinner />;
    }

    if ( this.props.error ) {
      return <Fatal message={ this.props.error } />;
    }

    return (
      <Table users={ this.props.users } />
    );
  };

  render() {
    return <>{ this.putContent() }</>;
  }
}

const mapStateToProps = (reducers) => {
  return reducers.usersReducer;
};

export default connect(mapStateToProps, usersActions)(Users);

Este es mi Users/Table.js:

import React from 'react';
import Row from './Row';

export default ({ users }) => {
  return (
    <table className='table'>
      <thead>
      <tr>
        <th>Name</th>
        <th>Email</th>
        <th>Website</th>
      </tr>
      </thead>
      <tbody>
      {
        users.map(user => (
          <Row user={user} />
        ))
      }
      </tbody>
    </table>
  );
}

Y este es mi Users/Row.js:

import React from 'react'

export default ({ user }) => {
  return (
    <tr key={ user.id }>
      <td>{ user.name }</td>
      <td>{ user.email }</td>
      <td><a href={user.website}>{ user.website }</a></td>
    </tr>
  )
}

Para formatear el c贸digo sin mucho esfuerzo pueden usar prettier en su proyecto y/o en su editor de preferencia. Yo lo configuro para que cada vez que guarde el archivo formatee automaticamente mi c贸digo.

No me canso de decir, excelente forma de ense帽ar, muy detallista en todo, esta genial 馃槂

Excelente profesor, la verdad de los mejores Felicidades a Freddy y a Platzi por estar tan comprometidos con la ense帽anza.
Saludos.

Ya que estamos usando Redux, tambi茅n lo conveniente ser铆a que el componente Fatal tom茅 las propiedades del store

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

const FatalError = (props) => (
    <h2 className="center red">
        {props.error}
    </h2>
)

const mapStateToProps = (reducers) => {
    return reducers.usersReducer
}

export default connect(mapStateToProps)(FatalError)

Y si quiere simplificar un poco m谩s la funci贸n de mapStateToProps, lo pueden hacer as铆:

const mapStateToProps = reducers => reducers.usersReducer

Las arrow functions tambi茅n funcionan as铆 cuando regresan un solo objeto.

quiero eso atajos. como lo saco en visual studio.

Configuraci贸n de prettier en Vcode
Ir al icono de extenciones y buscar Prettier formatter for Visual Studio Code e instalarlo, luego ir a la siguiente ruta:

Archivo/Preferencias/Configuracion dar clic en la parte superior donde aparecen dos llaves ** {}** y en el archivo json que se abre agregar las siguientes lineas de c贸digo:

鈥渆ditor.formatOnPaste鈥: true,
鈥渆ditor.formatOnSave鈥: true,
鈥渆ditor.formatOnType鈥: true,
鈥減rettier.eslintIntegration鈥: true,

por ultimo guardamos los cambios y listo. Disfruta de un c贸digo formateado autom谩ticamente cada que realices cambios y los guardes.

Saludos: 馃え馃え馃憤

En esta clase lo que hicimos fue un componente tabla (saca la info de redux) que tiene la tabla y la llamamos en usuarios.

CONCLUSI脫N modulo, nos ayudamos con los types colocando variables, manejamos los tres estados de la petici贸n HTTP Cargando, Error y exitosa la operaci贸n y limpiamos un poco el componente usuarios, pasamos la tabla a su propio componente y la llamamos en usuarios

Hola, le agregu茅 unas clases al h1 de Usuarios con las clases que ya estaban de la siguiente manera:

        <h1 className="center margen">
          Usuarios
        </h1>

Yo realice lo mismo pero pasando por las props los usuarios y utilizando el renderizado condicional

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

import * as userAction from "../../actions/userAction";

import Error from "../Fatal";
import Spinner from "../Spinner";
import Table from "../Table";

class usuarios extends Component {
  constructor(props) {
    super(props);
    this.state = {
      usuarios: [],
    };
  }

  componentDidMount() {
    this.props.traerTodos();
  }

  render() {
    console.log(this.props);
    return (
      <div className="margen">
        {this.props.cargar ? (
          <Spinner color="red" />
        ) : (
          <>
            {this.props.error ? (
              <Error error={this.props.error} />
            ) : (
              <Table usuarios={this.props.usuarios} />
            )}
          </>
        )}
      </div>
    );
  }
}

const mapStateToProps = (reducers) => {
  return reducers.userReducers;
};

export default connect(mapStateToProps, userAction)(usuarios);

Tabla como componente

El this solamente se utiliza cuando estamos en un componente clase.

Creamos un componente llamado 鈥楾abla.js鈥:

import React from 'react'
import { connect } from 'react-redux'

const Tabla = (props) => {
  /* Por cada usuario, tendr茅 una fila */
  const ponerFilas = () => props.usuarios.map((usuario) => (
    <tr key={ usuario.id }>
			<td>
				{ usuario.name }
			</td>
			<td>
				{ usuario.email }
			</td>
			<td>
				{ usuario.website }
			</td>
		</tr>
  ))

  return (
    <div>
      <table className="tabla">
        <thead>
          <tr>
            <th>Name</th>
            <th>Correo</th>
            <th>Enlace</th>
          </tr>
        </thead>
        <tbody>
          { ponerFilas() }
        </tbody>
      </table>
    </div>
  )
}

const mapStateToProps = (reducers) => {
  return reducers.usuariosReducer
}

export default connect(mapStateToProps)(Tabla)

Modificamos el index.js de los usuarios:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import Loader from '../General/Loader';
import Fatal from '../General/Fatal';
import Tabla from './Tabla';
import * as usuariosActions from '../../actions/usuariosActions';

class Users extends Component {

  componentDidMount() {
    this.props.traerTodos();
  }

  ponerContenido = () => {
    if (this.props.cargando) {
      return <Loader />;
    }

    if (this.props.error) {
      return <Fatal mensaje={ this.props.error } />;
    }

    return <Tabla usuarios={this.props.usuarios} />;
  }

  render(){
    return (
      <div>
        <h1>Usuarios</h1>
        { this.ponerContenido() }
      </div>
    )
  }

}

const mapStateToProps = (reducers) => {
  return reducers.usuariosReducers;
}

export default connect(mapStateToProps, usuariosActions)(Users);

Es genial como a partir de errores que van surgiendo se van revelando todos los detalles de Redux. Me encanta esta manera de plantear las clases, muy inteligente y entretenido.

import React from 'react'

const Row = ({ name, email, website }) => (
  <tr >
    <td>{ name }</td>
    <td>{ email }</td>
    <td><a href='/' target="_blank">{ website }</a></td>
  </tr>
)

export default Row
import React from 'react'
import { connect } from 'react-redux'

import Row from './Row'

const Table = ({ users }) => {
  return (
		<div>
			<table className="tabla">
				<thead>
					<tr>
						<th>Name</th>
						<th>Email</th>
						<th>Link</th>
					</tr>
				</thead>
				<tbody>
					{ users.map(user => <Row key={user.id} {...user} />) }
				</tbody>
			</table>
		</div>
	);
}

const mapStateToProps = (reducers) => {
  return reducers.userReducer
}

export default connect(mapStateToProps)(Table)

El this es para los componente clase.
隆Qu茅 bueno que es repasar hasta fijar!
Comparto mi apunte en el minuto 5 de esta (parecia simple de entrada pero) brillante clase.
Y que bien marcado Redux al final! EXCELENTE!
![](

Me gusto esta clase, mas que todo cuando el codigo es mas legible para cualquiera.CREO que soy fanatico al codigo limpio.

Aunque creeer铆a que ser铆a mejor enviar los datos como propiedad en lugar de conectarlos con Redux. Porque al conectarlos, se estar铆a perdiendo la esencia de ser reutilizable.

tu interface anda muy peque帽o, estaria bien si le das ctrl +

yo agregue un condicional mas en poner contenido, que valida si los datos que nos llegan de la peticion estan vacios los manejamos

// si los datos estan vacios
		if (this.props.usuarios.length === 0) {
			return (
				<div>
					<h3>Datos vacios</h3>
				</div>
			);
		}```

Este profesor ense帽a muy bacano! Estoy entendiendo muucho mejor Redux

// Users.js
import React from 'react';
import { connect } from 'react-redux';
import * as usersActions from '../../actions/usersActions';
import { Spinner } from '../Spinner';
import { Fatal } from '../Fatal';
import Table from './Table';
import '../../styles/components/Users.css';

class Users extends React.Component {
  componentDidMount() {
    this.props.getUsers();
  }

  showContent = () => {
    // Loading state
    if (this.props.loading) 
      <Spinner />

    // Error state
    if (this.props.error)
      <Fatal message={this.props.error}/>

    // Success state
    return <Table users={this.props.users}/>
  }

  render() {
    return (
      <div className="Users">
        <h1>Users</h1>
        {this.showContent()}
      </div>
    )
  }
}

const mapStateToProps = (reducers) => {
  return reducers.usersReducer;
}

export default connect(mapStateToProps, usersActions)(Users);


// Table.js
import React from 'react';
import { connect } from 'react-redux';

const Table = (props) => {
  const drawUserRows = () => props.users.map(
    (user) => (
      <tr key={user.id}>
        <td>{user.name}</td>
        <td>{user.email}</td>
        <td>{user.website}</td>
      </tr>
    )
  )
  
  return (
    <table className="App">
      <thead>
        <tr>
          <th>
            Nombre
          </th>
          <th>
            Correo
          </th>
          <th>
            Enlace
          </th>
        </tr>
      </thead>
      <tbody>
        {drawUserRows()}
      </tbody>
    </table>
  )
}

const mapStateToProps = (reducers) => {
  return reducers.usersReducer
}

export default connect(mapStateToProps)(Table);

Es demasiada buena la clase, demasiada la verdad, justo lo necesario.

Excelente clase. 馃檪

Lo que se hizo en esta clase fue crear un componente exclusivo para la tabla de usuarios y manejarlo en un archivo externo al index.js para hacer mas practico y fragmentado el codigo

tambien se pueden pasar mediante props los users y en el componente que renderiza la tabla, destructurar el props para obtener el arreglo en cuestion

En componente Users.js

return <UsersTable users={this.props.users} />;

En componente UsersTable.js

const UsersTable = ({ users }) => {
	return (
		<table className='table-width'>
			<thead>
				<tr>
					<th>Name</th>
					<th>Email</th>
					<th>Website</th>
				</tr>
			</thead>
			<tbody>
				{users.map(item => (
					<tr key={item.id}>
						<td>{item.name}</td>
						<td>{item.email}</td>
						<td>{item.website}</td>
					</tr>
				))}
			</tbody>
		</table>
	);
};

Hay alguna diferencia si coloco la funci贸n que renderiza las filas fuera de la funci贸n padre?

const renderRows = (users) => {
	return users.map((item, idx) => {
	  return (
	    <tr key={idx}>
	      <td>{item.name}</td>
	      <td>{item.email}</td>
	      <td>{item.website}</td>
	    </tr>
	  );
	});
};

const UsersTable = ({ loading, error, users }) => {

	if (loading) {
      return <Roller/>
    }
    if (error) {
      return <Fatal error={error} />
    }
	  //console.log(error ? error.message : "nein!!")
	return <Table>
	    <thead>
	      <tr>
	        <th>Nombre</th>
	        <th>Correo</th>
	        <th>Enlace</th>
	      </tr>
	    </thead>
	    <tbody>{renderRows(users)}</tbody>
	  </Table>
}```

Excelente

Tenia un error y no me hab铆a dado cuenta. En la funci贸n ponerContenido() dentro del primer condicional hab铆a puesto que me retornara el spinner y que revisara el condicional de error (lo puse donde no era) y a煤n as铆 funcionaba.

Excelente contenido

Pregunta.
Es necesario la funci贸n de traer todo el contenido? no se puede hacer los IFs dentro del return padre(index.js de usuarios)?
o por qu茅 de la funci贸n? es una buena practica?

No entend铆 muy bien por que no hizo falta pasar un action creator en el connect.

Buen铆sima clase!

genial, estos extras en el campo laboral no son tan extras