Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Validación para LogIn LogOut

20/29
Recursos

Aportes 64

Preguntas 17

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

por primera vez en el curso logre entender el funcionamiento de los reducer y actions y logre codear el logout sin ver la clase

Al fin pude entender el sentido de Redux, definitivamente es necesario practicar e intentar hacer las cosas sin ayuda.

Básicamente, la función connect recibe dos parámetros

mapStateToProps y mapDispatchToProps

En palabras resumidas, la primera solicita datos del store(la base de datos)
y el segundo envía datos.

Así solamente hay un flujo de datos y todo es mas simple. Me exploto la cabeza. Animo para aquellos que aun están batallando

Reto:

import PropTypes from 'prop-types';
...
Header.propTypes = {
  user: PropTypes.object
}

Hola creo que todo se peude poner dentro de una validacion de hasUser no necesitamos dos :

 {hasUser ? (
            <>
              <li>
                <a href='/'>{user.name}</a>
              </li>
              <li>
                <a href='#logout' onClick={handleLogout}>Cerrar Sesión</a>
              </li>
            </>
          ) : (
            <li>
              <Link to='/login'>Iniciar Sesión</Link>
            </li>
          )}```

Epico! con redux y configurando los actions manejando todo desde un mismo estado es increíble cómo se ahorra código y todo sale como magia. Hermoso!

Nota: al principio pensé que mapDispatchToProps se tenía que llamar así por obligación, pero yo le puse mapActions e igual funciona.

const mapActions = {
  logoutRequest
}


export default connect(mapStateToProps,mapActions)(Header)

Este era el ejemplo que buscaba sobre como conviven ambas partes, el mapStateToProps y el mapDispatchToProps

Reto:

Header.propTypes = {
  user: PropTypes.object.isRequired,
  logoutRequest: PropTypes.any.isRequired,
};

Muy bien explicado, de los mejores profes, demuestra experiencia y transmite seguridad.
Hacer un breve repaso al final de la clase es muy útil para atar cabos sueltos. Deberían realizarlo más seguido los otros profes cuando se abarcan varios conceptos que pueden ser confusos. 🙃

Reto:
CarouselItem.jsx

CarouselItem.propTypes = {
  id: PropTypes.number,
  cover: PropTypes.string,
  title: PropTypes.string,
  year: PropTypes.number,
  contentRaiting: PropTypes.string,
  duration: PropTypes.number,
  isList: PropTypes.bool,
  setFavorite: PropTypes.func,
  deleteFavorite: PropTypes.func,
};

Header.jsx

Header.propTypes = {
  user: PropTypes.object,
  logoutRequest: PropTypes.func,
};
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import gravatar from '../utils/gravatar';
import { logoutRequest } from '../actions';
import '../assets/styles/components/Header.scss';
import logo from '../assets/static/logo-platzi-video-BW2.png';
import userIcon from '../assets/static/user-icon.png';

const Header = (props) => {
  const { user } = props;
  const hasUser = Object.keys(user).length > 0;

  const handleLogout = () => {
    props.logoutRequest({});
  };

  return (
    <header className='header'>
      <Link to='/'>
        <img className='header__img' src={logo} alt='Platzi Video' />
      </Link>
      <div className='header__menu'>
        <div className='header__menu--profile'>
          {hasUser ?
            <img src={gravatar(user.email)} alt={user.email} /> :
            <img src={userIcon} alt='iconodeusuario' />}
          <p>Perfil</p>
        </div>
        <ul>
          {hasUser ?
            <li><a href='/'>{user.name}</a></li> :
            null}
          {hasUser ?
            <li><a href='#logout' onClick={handleLogout}>Cerrar Sesión</a></li> : (
              <li>
                <Link to='/Login'>
                  Iniciar sesión
                </Link>
              </li>
            )}
        </ul>
      </div>
    </header>

  );
};
const mapStateToProps = (state) => {
  return {
    user: state.user,
  };
};

const mapDispactchToProps = {
  logoutRequest,
};

Header.propTypes = {
  user: PropTypes.object,
  logoutRequest: PropTypes.func.isRequired,
};

export default connect(mapStateToProps, mapDispactchToProps)(Header);

import PropTypes from 'prop-types';
Header.propTypes = {
  user: PropTypes.object,
  logoutRequest: PropTypes.func,
};

para que sirve la parte de object.keys(user) ?

El user.name no tiene ningun valor

Reto

import PropTypes from 'prop-types';

Header.propTypes = {
  user: PropTypes.object,
  logoutRequest: PropTypes.func,
};

Reto

import PropTypes from 'prop-types';
Header.propTypes = {
  user: PropTypes.object,
  logoutRequest: PropTypes.func.isRequired,
};```

No puedo creerlo … 3 clases con el mismo error, revisen bien su código.
En login.jsx

const handleSubmit = (event) => {
    event.preventDefault(); //*Para que no se haga la acción de enviar formulario
    props.loginRequest(form);
    props.history.push('/'); //*Redirigimos al usuario al home
  };

loginRequest NECESITA EL PARAMETRO DE FORM. Si no, no funciona el login.

Apuntes extras:

Básicamente, la función connect recibe dos parámetros:

  1. mapStateToProps
  2. mapDispatchToProps

En palabras resumidas, la primera solicita datos del store(la base de datos)
y el segundo envía datos y dispara acciones para interactuar con el store.

Así solamente hay un flujo de datos y todo es mas simple.

Documentación oficial de Verificación de tipos con PropTypes - React

PropTypes en NPM

En esta clase, varios compañeros lograron entender, y yo también pude hacerlo. Es increíble la sensación de poder entender y mejorar cada día como Frontend.

@TeamPlatzi deberían actualizar la sección de React Router DOM

Para para saludar al usuario se puede añadir el nombre: en Login.jsx:

 const [form, setValues] = useState({
    name: "",
    email: "",
    password: "",
  });

<input
           name="name"
           className="input"
           type="text"
           placeholder="Nombre"
           onChange={handleInput}
         />


y en Header.jsx:

{hasUser ? (
            <>
              <li>
                <a href="/">{`Bienvenido ${user.name}`}</a>
              </li>
              <li>
                <a href="#logout" onClick={handleLogout}>
                  Cerrar Sesión
                </a>
              </li>
            </>

Reto superado

Por experiencia de usuario, creo que en lugar de mostrarle la seccion de perfil cuando aun no ha hecho login, podrian mostrarle directamente el enlace del login con un renderizado condicional. Asi, el usuario vera una imagen y un menu solo cuando este logeado…

Vamos a trabajar las validaciones con nuestro header que nos permitira saber si estamos logeados o no.

Crearemos la validacion en nuestro menu, donde teniamos cuenta o iniciar sesion. Y Utilizaremos a hasUser para poder confimarlo. Primero crearemos validaciones para la interfaz

<ul>
          {hasUser ? <a href="/">{user.name}</a> : null}

          {hasUser ? (
            <li>
              <a href="#logout" onClick={handleLogout}>
                Cerrar Sesion
              </a>
            </li>
          ) : (
            <li>
              <Link to="/login">Iniciar Sesión</Link>
            </li>
          )}
        </ul>

Asi nuestro menu se vera diferente en cao de que iniciemos o no sesion

Ahora crearemos un action nuevo para poder desloguearnos, esto en actions

export const logoutRequest = (payload) => ({
  type: "LOGOUT_REQUEST",
  payload,
});

Ahora lo importaremos en Header

import { logoutRequest } from "../actions";

Pero recordemos que tenemos que mapiar nuestra informacion

const mapDispatchToProps = {
  logoutRequest,
}

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

Ahora vamos en la funcion hacer lo siguiente:

const handleLogout = () => {
    props.logoutRequest({});
  };

Donde le mandaremos un objeto vacio y asi simular un logout.

Ahora solo crearemos nuestro reducer

case "LOGOUT_REQUEST":
      return {
        ...state,
        user: action.payload,
      };

Otra forma de mapear los actions:
export default connect(mapStateToProps, { logoutRequest })(Header);

De esta forma te ahorras hacer la funcion mapDispatchToProps.

de verdad que escogí el peor curso para hacer un proyecto personalizado, este era el que tenia que seguir al pie de la letra

es interesante como en todo el proyecto no se generó una configuración de eslint o prittier

Hasta aquí parece ordenado, pero me preocupan los estilos CSS,

Depronto me perdi de algo pero cuando el profe le pone nombre a las funcion como mapDispatchToProps es por que debe ser asi o por que el quiere ponerle asi ? 🤔🤔

Podríamos modificar la etiqueta a por un Link ya que de esta forma cuando cerremos sesión no se recargue nuestra página 😄

Seria algo así lo del reto pero no entiendo por que se pasan esos proptypes.

import PropTypes from 'prop-types';

Header.propTypes = {
  user: PropTypes.object,
  logoutRequest: PropTypes.func,
};

Es correcto poner como proptypes las props de redux? O solo se ponen las que puede recibir el componente si es instanciado por otro?

a

Practicas:

Qué tal, ¿cómo le puedo hacer para que persistan los datos del usuario previamente logrado cuando recargue la pagina o vuelva a abrir el navegador?

¿A alguíen más le aparece la contraseña cuando inician sesión?

profe excelente forma de explicar

Como seria para hacer esta misma validacion pero con hooks?

Reto:

import PropTypes from 'prop-types';
// ...
Header.propTypes = {
    user: PropTypes.object,
    logoutRequest: PropTypes.func,
}
// ...

Una validación mas simple:

{ hasUser && <li><a href="/">Cuenta</a></li> }

Para la validacion seria desde el login antes de estar en header

Que buen curso 😄

No queda iniciada la sesión simulada. Siempre redirecciona al home pero me sigue apareciendo iniciar sesión, y gravatar tampoco lo toma.

import Proptypes from 'prop-types';

Header.propTypes = {
    user: Proptypes.object,
    logoutRequest: Proptypes.func,
}

He llegado hasta aquí y no me queda claro como funciona lo de mandar un objeto vacío para reiniciar el estado (State)

Muy bueno!

Quise hacer que cuando cerrará sesión, le den en logoutRequest luego pueda ir a la ruta /login pero me da este error:

Este es el código que coloque:

const handleLogout = () => {
        props.logoutRequest({});
        props.history.push("/login");
    }

¿Que podría estar mal?

Me está costando mucho más que antes seguir la lógica que se usa. Voy a tener que repasar bastante

Reto de autenticar los props con los propTypes

// validaciones con prop-types
Header.propTypes = {
  // el user debe de ser un objeto
  user: propTypes.object,
  // el logoutRequest debe ser una funcion
  logoutRequest: propTypes.func,
};

mi propuesta para el menu

<ul>
  {hasUser ? (
    <>
      <li>
        <Link to='/login'>{user.email}</Link>
      </li>
      <li>
        <a href='#logout' onClick={handleLogout}>
          Cerrar Sesión
        </a>
      </li>
    </>
  ) : (
    <li>
      <Link to='/login'>Iniciar Sesión</Link>
    </li>
  )}
</ul>;

Hola! Buena clase!


.

hasUser=> Nos va a permiti saber si tenemos o no una cuenta iniciada.







Estuvo excelente la clase, Redux es como magia… Con apenas unas líneas de código cambiamos el estado de un componente, y no nos preocupamos por datos redundantes porque todo viene de un solo lugar, el store! GENIAL

Para los que vieron el detalle de user.name, cámbienlo a user.email. Y si se les desborda el contenido, pueden modificar la propiedad width del ul a max-content.

Alguien me podría decir una definición de Payload?

El reto quedaría así :

import PropTypes from "prop-types";
..........
Header.propTypes = {
  user: PropTypes.object.isRequired,
  logoutRequest: PropTypes.func,
}
Header.propTypes = {
  user: PropTypes.object.isRequired,
  logoutRequest: PropTypes.func.isRequired
}```

`import PropTypes from ‘prop-types’;

Header.propTypes = {
user: PropTypes.object,
logoutRequest: PropTypes.func,
};`

{
                        hasUser ? 
                        <>
                            <li><a href="/">{user.name}</a></li>
                            <li>
                                <a href="#" onClick={handlerLogout}>Cerrar Sesión</a>
                            </li>
                        </>:
                        <li>
                            <Link to="/login">Iniciar sesión</Link>
                        </li>
                    }

Hola gente, tengo un Warnig al agregar los propTypes, me corre bien el sitio, pero en consola me muestra este mensaje

En este ejemplo de login y logout, tanto las acciones como los reducers están comportandose de la misma manera y esto, en proyectos grandes se convierte en redundancia de código. El siguiene patrón puede ser usado:

accion/index.js

export const manageLogin = payload => ({
  type: "MANAGE_LOGIN",
  payload,
});

accion/index.js

case "MANAGE_LOGIN":
  return {
    ...state,
    user: action.payload,
};

No entiendo la funcionalidad de PropTypes, para que se usan? son relevantes? existe alguna clase donde lo expliquen?

Porque en la validacion hasuser usa la etiqueta <a> en vez de <Link>?

Muy bien!

Dejo mio reto y la documentaciòn de propTypes que està buenisima para entender, ya que en principio habìa puesto a user : PropTypes.string, cuando realmente es PropTypes.object.
Ademas la misma documentaciòn brinda un montòn de hacks para que puedas hace aùn màs puntual tus especificaciones.

Header.propTypes = {
    user : PropTypes.object.isRequired,
    logoutRequest :  PropTypes.func. 
}

https://es.reactjs.org/docs/typechecking-with-proptypes.html

Como puedo inyectar el history en las props del header?, en los demás componentes si me funciona pero en el header no, no sé si este relacionado con que no esta directamente agregado en las rutas.