No tienes acceso a esta clase

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

Curso de React Router 5 y Redux

Curso de React Router 5 y Redux

Oscar Barajas Tavares

Oscar Barajas Tavares

Crear Formulario de Login

16/29
Recursos

Aportes 40

Preguntas 15

Ordenar por:

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

Tengan en cuenta que su botón tiene que ser de tipo submit para que funcione.

En esta clase de React con Richard se explica como se agregan los valores dinamicos del formulario. Minuto 4:00. Clase de React

Otra forma de manejar forms con react es : Formik y react-redux-form

Otra forma de hacerlo es usando useReducer de React Hooks. Dejo mi codigo y el resultado.

Si usan prettier agreguen esta linea a su config para que él quite los parentesis cuando solo haya un parametro

"prettier.arrowParens": "avoid",

Reto completado, aquí está mi UI mejorada del Login y de Register 💚💚💚
.

.

Una duda, ¿Por que se pone event.target ?

en las devtools podemos observar los props que tiene cada componente, es una ayuda muy grande para debuggear también

Tambien pueden usar react-redux-form les ayuda . amanejar los estados y les ayud a aimplementar validaciones

Por si alguien se quedó con la duda:

    const handleInput = event => {
        setValues({
            ...form,
            [event.target.name]: event.target.value   // <---
        });
    }

Esta forma de inicializar un objeto dinámicamente se añade con ES6(Referencia)

Y sobre la función de actualización del estado:

       setValues({
            ...form,
            [event.target.name]: event.target.value
        });

Al utilizar el operador de propagación, se está manteniendo el estado anterior y añadiendo uno nuevo, es decir, si tuviesemos ‘n’ inputs todos se almacenarían, para entender mejor este comportamiento, pueden comentar la línea del operador spread y ver como cuando se da submit solo se muestra el valor del último input modificado.

Login.jsx

import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import googleIcon from '../assets/img/google-icon.png';
import twitterIcon from '../assets/img/twitter-icon.png';
import '../assets/styles/containers/Login.scss';

const Login = () => {
  const [formValues, setFormValues] = useState({
    email: '',
    password: '',
  });

  const handleInput = (event) => {
    setFormValues({
      ...formValues,
      [event.target.name]: event.target.value,
    });
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    console.log('formValues', formValues);
  };

  return (
    <section className='Login'>
      <section className='Login__container'>
        <h2>Inicia sesión</h2>
        <form
          className='Login__container--form'
          action=''
          onSubmit={handleSubmit}
        >
          <input
            className='input'
            type='text'
            name='email'
            id='email'
            placeholder='Correo'
            onChange={handleInput}
          />
          <input
            className='input'
            type='password'
            name='password'
            id='password'
            placeholder='Contraseña'
            onChange={handleInput}
          />
          <button className='button' type='submit'>Iniciar sesión</button>
          <div className='Login__container--remember-me'>
            <label htmlFor='cbox1'>
              <input type='checkbox' name='cbox1' id='cbox1' value='Checkbox' />
              Recuérdame
            </label>
            <Link to='/forgot-password'>
              Olvidé mi contraseña
            </Link>
          </div>
        </form>
        <section className='Login__container--social-media'>
          <div>
            <img src={googleIcon} alt='Google' />
            inicia sesión con Google
          </div>
          <div>
            <img src={twitterIcon} alt='Twitter' />
            inicia sesión con Twitter
          </div>
        </section>
        <p className='Login__container--register'>
          No tienes ninguna cuenta?
          <Link to='/register'>
            Regístrate
          </Link>
        </p>
      </section>
    </section>
  );
};

export default Login;

Para quien le sirva encontré la forma de cambiar el color del header según la ruta en la que te encuentres.

Primero nos ubicamos en el componente Header para agregarle una propiedad y poder cambiarle el estilo “dinámicamente”:

const Header = ({ color }) => (
  <header className={`header ${color}`} > ...

Como ven le agregué la propiedad llamada color (No se me ocurrió un mejor nombre 🥴) que esta la vamos a agregar al className de <header>, dejando su clase original .header para no afectar la estructura ni posicionamiento.

Luego nos dirijimos al componente Layout que es donde importamos el componente Header.

Necesitamos importar useLocation de router DOM

import { useLocation } from 'react-router-dom';

Ahora como ya lo hemos hecho con muchos componentes, necesitamos adaptar nuestro componente Layout para agregar lógica.

const Layout = ({ children }) => {
    const pathname = useLocation().pathname; //Obtenemos la ruta actual

    return (
        <div className="App">
            {
                pathname == '/login' | pathname == '/register' ?
                    <Header color='header__login' /> :

                    <Header />
            }

            {children}

            <Footer />
        </div>
    );
};

En una constante pathname guardamos la ruta en la que nos encontremos actualmente al navegar en nuestra app por medio de useLocation().pathname.

Lo siguiente que hicimos fue hacer un condicional, en caso de que la ruta actual sea /login o /register usamos la etiqueta de nuestro componente Header con el valor de color='header__login' la cual es la clase CSS la cual contendrá solamente el color verde.

Agregamos dicha clase en Header.scss:

.header__login {
  background-color: #21c08b;
}

Ya con esto les debería funcionar, prueben cambiando del Home al Login, Register y viceversa.

trate de devolverme algunos videos para verlos de nuevo, pero aparecen al 100%.
porfa que aparezca el avance pero que el video vuelva a iniciar de 0

Hola, para hacer validaciones les sugiero usar los siguientes regex en el email y password:

const EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\[email protected]"]+(\.[^<>()\[\]\\.,;:\[email protected]"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
const PASSWORD_REGEX = /^(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[0-9])(?=.*?[!"#\$%&'\(\)\*\+,-\.\/:;<=>\[email protected][\]\^_`\{\|}~])[a-zA-Z0-9!"#\$%&'\(\)\*\+,-\.\/:;<=>\[email protected][\]\^_`\{\|}~]{6,}$/

El primero lo obtuve de aquí, el segundo de aquí.

Para enviar al usuario un mensaje de éxito o fracaso puede usar SweetAlert2.

Finalmente, les comparto mis validaciones

const handleSubmit = e => {
  e.preventDefault()
  console.log(form)

  if (!EMAIL_REGEX.test(form.email))
    return Swal.fire({
      icon: 'error',
      title: 'Email inválido',
      text: 'Debes ingresar un email válido'
    })

  if (!PASSWORD_REGEX.test(form.password))
    return Swal.fire({
      icon: 'error',
      title: 'Contraseña inválida',
      html: 'Debes ingresar una contraseña con:<br><br>' + 
        '- 6 caracteres<br>' +
        '- Una minúsclia<br>' +
        '- Una mayúsclia<br>' +
        '- Un número<br>' +
        '- Un caracter especial<br>'
    })

  return Swal.fire({
    icon: 'success',
    title: 'Inicio de sesión exitoso',
    timer: 1500
  })
}

Happy coding!

No entiendo como el setValues “setea” los valores
Este codigo en especifico, lo desestructura el form y ¿Despues que?

 const handleInput = (event) => {
    setValues({
      ...form,
      [event.target.name]: event.target.value,
    });
  };```

Una pregunta, por qué se utilizan los [] en [event.target.name]:event.target.value ?

repasando la clase , estupendo

Igual también podemos poner un objeto vació en nuestro useState y funcionara.

Buen dia companeros, tengo un problema con el formulario. No de imprime nada en consola, aunque si ejecuta el “preventDefault()”.

Alguna sugerencia que explique el porque no imprime nada en consola?

import React, { useState } from "react";
import { Link } from "react-router-dom";
import "../assets/styles/components/Login.scss";
import googleIcon from "../assets/static/google-icon.png";
import twitterIcon from "../assets/static/twitter-icon.png";

const Login = () => {
  const [form, setValues] = useState({
    email: ""
  });
  const handleInput = event => {
    setValues({
      ...form,
      [event.target.name]: event.target.value
    });
  };
  const handleSubmit = event => {
    console.log("hello");
    console.log(form);
    event.preventDefault();
  };
  return (
    // componente funcional
    <section className="login">
      <section className="login__container">
        <h2>Inicia sesión</h2>
        <form
          className="login__container--form"
          onSubmit={() => handleSubmit()}
        >
          <input
            name="email"
            className="input"
            type="text"
            placeholder="Correo"
            onChange={() => handleInput}
          />
          <input
            name="password"
            className="input"
            type="password"
            placeholder="Contraseña"
            onChange={() => handleInput}
          />
          <button type="button" className="button">
            Iniciar sesión
          </button>
          <div className="login__container--remember-me">
            <label htmlFor="cbox1">
              <input type="checkbox" id="cbox1" value="first_checkbox" />
              Recuérdame
            </label>
            <a href="/">Olvidé mi contraseña</a>
          </div>
        </form>
        <section className="login__container--social-media">
          <div>
            <img src={googleIcon} alt="google" />
            Inicia sesión con Google
          </div>
          <div>
            <img src={twitterIcon} alt="Twitter" />
            Inicia sesión con Twitter
          </div>
        </section>
        <p className="login__container--register">
          No tienes ninguna cuenta
          <Link to="/register">Regístrate</Link>
        </p>
      </section>
    </section>
  );
};

export default Login;

Este es un interesante artículo sobre React Hooks y Redux https://latteandcode.medium.com/react-hooks-y-redux-funcionando-juntos-869d2900f0cb

Se puede utilizar una extensión para Chrome: Redux DevTools: https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd?hl=es

keyloggers 😍

En el login lo que necesitamos es obtener la informacion que el usuario va a ingresar para pasarla a nuestro flujo de informacion.

Primero en nuestro de componente de login tenemos que ubicar nuestros inputs y ahora lo trabajaremos con Hooks. Ahora necesitamos cambiar nuestro componente de PRESENTACIONAL a STATELESS.

Ahora usaremos el useState, uno donde utilizaremos una constate donde trae dos valores, el formulario y otro guardar los valores.

const [form, setValues] = useState({
        email:'',
    })

Donde inicializamos para que nuestros valores tengan un estado. Ahora tenemos que manejar los cambios en los INPUT, y ahora que los manejemos tenemos que usar el HandleSubtmit con el que vamos a poder enviar esta informacion a algun valor particular.

Ya que lo tengamos necesito crear una funcion donde tengamos todos los valores que cambian del input con:

const handleInput = (event) => {
    setValues({
      ...form,
      [event.target.name]: event.target.value,
    });
  };

Ahora nuestro formualrio donde haremos nuestro submit del formulario, para ver que es lo que hace, al igual que un evento para que cancele los datos default de HTML

const handleSubmit = (event) => {
    event.preventDefault();
    console.log(form);
  };

Ahora solo ponemos las funciones del input en el onChange y las del Submit en el formulario

Porque pone el email sin nada? Eso me provoco que me aparecieran 2 emails en el objeto

¿Por que ir guardando letra a letra y no esperar al final que aplaste el boton para llevar todo el input?

Por alguna misteriosa razón el evento me devuelve un null

¡Pleasure!


…
…

…

no entiendo de donde saca el target 😦

Recordar: Usamos hooks con useState.

Para obtener los datos de un formulario;

Login.jsx:

import React, { useState } from 'react';

const Login = () => {

  const [form, setValues] = useState({
    email: '',
  });

  const handleInput = (event) => {
    setValues({
      ...form,
      [event.target.name]: event.target.value,
    });
  };

  const handleSubmit = (event) => {
    event.preventDefault(); //*Para que no se haga la acción de enviar formulario
    console.log(form);
  };

  return (
  <form
    className='login__container--form'
    onSubmit={handleSubmit}
  >
    <input
      name='email'
      className='input'
      type='text'
      placeholder='Correo'
      onChange={handleInput}
    />
    <input
      name='passwrod'
      className='input'
      type='password'
      placeholder='Contraseña'
      onChange={handleInput}
    />
  </form>
  );
};

A mi me gusta más desestructurando de una vez el objeto event:
.

const handleInput = ({target}) =>{
  setValues({
    ...form,
    [target.name]: target.value
  })
} 

Cuando se agrega un <button> dentro de un <form> este toma por default un type submit. Cuando un button es de tipo submit, al hacer click en el mismo se envia el form como form-data, y si es algo que quieres evitar para manejar el formulario tu mismo, entonces es necesario aplicar el event.preventDefault() que se observa en la clase.

Si no tienes ningun button con type submit, entonces no es necesario agregar el preventDefault.

Ctrl + shift + i = Format code in Visual Code Studio ubuntu

Les dejo las recomendaciones de eslint para el correcto uso de button con su type explicito:
Fuente

Ejemplos del uso incorrecto:

`var Hello = <button>Hello</button>
var Hello = <button type=“foo”>Hello</button>
var Hello = <button type={foo}>Hello</button>

var Hello = React.createElement(‘button’, {}, ‘Hello’)
var Hello = React.createElement(‘button’, {type: ‘foo’}, ‘Hello’)`

Ejemplos del uso correcto:

`var Hello = <span>Hello</span>
var Hello = <span type=“foo”>Hello</span>
var Hello = <button type=“button”>Hello</button>
var Hello = <button type=“submit”>Hello</button>
var Hello = <button type=“reset”>Hello</button>
var Hello = <button type={condition ? “button” : “submit”}>Hello</button>

var Hello = React.createElement(‘span’, {}, ‘Hello’)
var Hello = React.createElement(‘span’, {type: ‘foo’}, ‘Hello’)
var Hello = React.createElement(‘button’, {type: ‘button’}, ‘Hello’)
var Hello = React.createElement(‘button’, {type: ‘submit’}, ‘Hello’)
var Hello = React.createElement(‘button’, {type: ‘reset’}, ‘Hello’)
var Hello = React.createElement(‘button’, {type: condition ? ‘button’ : ‘submit’}, ‘Hello’)`

  const [formValues, setFormValues] = useState({ email: "", password: "" });

  const handleInputChange = ({ target }) => {
    setFormValues({
      ...formValues,
      [target.name]: target.value,
    });
  };

  const submitForm = (event) => {
    event.preventDefault();
    console.log(formValues);
  };```

No entiendo muy bien como funciona el handleInput por ejemplo

[event.target.name] : event.target.value

porque el name esta entre corchetes

lets go for more!!

![](

Lo arregle con esta propiedad de css

  • box-sizing: content-box;

Gracias 😄

Práctica: esto esta genial!!!