No tienes acceso a esta clase

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

Curso de React.js 2019

Curso de React.js 2019

Richard Kaufman

Richard Kaufman

Manejo de estado

15/37
Recursos

Hasta esta clase todos los componentes han obtenido su información a través de props que vienen desde afuera (otros componentes) pero hay otra manera en la que los componentes pueden producir su propia información y guardarla para ser consumida o pasada a otros componentes a través de sus props. La clave está en que la información del state a otros componentes pasará en una sola dirección y podrá ser consumida pero no modificada.

  • Para guardar la información en el estado se usa una función de la clase component llamada setState a la cual se le debe pasar un objeto con la información que se quiere guardar.
  • Aunque no se ve, la información está siendo guardada en dos sitios. Cada input guarda su propio valor y al tiempo la está guardando en setState, lo cual no es ideal. Para solucionarlo hay que modificar los inputs de un estado de no controlados a controlados.

Aportes 125

Preguntas 42

Ordenar por:

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

Llamo mi atención el siguiente error:

Palabras más, palabras menos el error dice:

“Un componente está cambiando un input no controlado a controlado. Decida si quiere que sea controlado o NO controlado y déjelo así toda su vida (la vida del componente claro).”

El error aquí es al momento que ReactDOM hace el render de nuestros inputs se topa con por poner un ejemplo el input del firstName:

      value={this.state.firstName}

this.state.firstName evalúa a undefined por no estar definidos desde el principio en el state . Por lo tanto ReactDOM decide que es un Input no controlado.

Cuando handleChange() es llamado y asigna un valor string al this.state.firstName, el input pasa de no controlado a controlado.

  handleChange = e => {
    this.setState({
      [e.target.name]: e.target.value,
    });
  };

Esto pasando en todos nuestros inputs menos en el del jobTitle porque ese sí lo definimos en el state al principio.

Mi solución fue definir valores default en el state:

  state = {
    firstName: '',
    lastName: '',
    email: '',
    jobTitle: '',
    twitter: ''
  };

Y chao error, espero les sirva.

más info en controlled-components

Recuerden que siempre es una buena practica poner placeholders a tus inputs, se hace declarando el Prop en el input de la siguiente manera:

<input type="text" placeholder="introduce tu nombre" />

Ademas de ser una buena practica, ayuda a lidiar con el principal problema del diseño de interfaces, el usuario, no importa que tan especifico sea, siempre habrá un usuario que no entienda o lo use mal.

Para los que necesitan teoría para entender las cosas, como yo, les dejo el pequño resumen de mí investigación:

El state en React es un objeto que deriva de la clase React Component. Puede definirse a sí mismo como un objeto qe almacena las propiedades observables que controlan el comportamiento del componente. (como en este caso el value de los inputs de los formularios)

👋Hola chicos
Este es el resumen de esta clase

El estado es por así decirlo un almacén que permite guardar los datos que produce un componente para ser utilizado para asimismo o ser pasado a otros componentes.

Para guardar o actualizar la información de un componente en su estado se usa una función llamada setState() la cual debe pasarse un objeto como parámetro para que sea guardada la información.

setState() puede ser utilizado cuando queramos guardar los datos (puede ser un formulario) después de escuchar un evento de un elemento (input, boton, etc).

state={}
handleChange = e => {
    this.setState({
	[e.target.name] : e.target.value,
      })
  }

Aunque no se ve, la información que se obtiene en el componente se guarda en dos sitios, en el state y en el elemento de un formulario (inputs, textarea, select, etc). Lo ideal es tener una sola fuente de información.

Para ello debemos modificar los elementos de un formulario de un estado no controlados (Normalmente los elementos de un formulario mantienen sus propios estados y los actualiza de acuerdo a la interacción del usuario) a controlados (que react sea la única fuente de verdad, es decir, que los valores obtenidos por los elementos del formulario sean controlados por react para mayor información ).

Esto se logra agregando un props llamado value al elemento del formulario para que obtenga la información que contiene el estado del componte.

<input value={this.props.firstName}>
</input>

Cuando se recarga la pagina , el props llamado value del elemento del formulario (el input en este caso) intentara leer los datos del estado, por ello es necesario inicializar state (ya sea vació o no vació) en el componente.

class BadgeForm extends React.Component{
	state={}
	handleChange = e => {
		[e.target.name] : e.target.value
	}
}

Dale un like en ❤ si te ayudo esta recomendación

Aqui el como se haria con hooks

import React, { useState } from "react";
const BadgeForm = () => {
  const [form, setValues] = useState({
    firstName: "",
    lastName: "",
    email: "",
    jobTitle: "",
    twitter: ""
  });
  const handleInput = event => {
    setValues({
      ...form,
      [event.target.name]: event.target.value
    });
  };

  const handleSubmit = event => {
    event.preventDefault();
    console.log(form);
  };
  return (
    <>
      <h1>New Attendat</h1>

      <form onSubmit={handleSubmit}>
        <div className="form-group">
          <label>First Name</label>
          <input
            onChange={handleInput}
            className="form-control"
            type="text"
            name="firstName"
            value={form.firstName}
          />
          <label>Last Name</label>
          <input
            onChange={handleInput}
            className="form-control"
            type="text"
            name="lastName"
            value={form.lastName}
          />
          <label>Email</label>
          <input
            onChange={handleInput}
            className="form-control"
            type="email"
            name="email"
            value={form.email}
          />
          <label>Job Title</label>
          <input
            onChange={handleInput}
            className="form-control"
            type="text"
            name="jobTitle"
            value={form.jobTitle}
          />
          <label>Twitter</label>
          <input
            onChange={handleInput}
            className="form-control"
            type="text"
            name="twitter"
            value={form.twitter}
          />
        </div>

        <button className="btn btn-primary">Save</button>
      </form>
    </>
  );
};

export default BadgeForm;

si quieren solucionar el error que sale al final de la clase en la consola deben darle un valor ya sea vacio o no al State
Ejemplo:

state = {
    firstName: "",
    lastName: "",
    email: "",
    jobTitle: "",
    twitter: "",
  }

Si la función definida para manejar el evento onChange no fue declarada como una arrow function si no que se declaró como una función más de la clase bajo la estructura de método tradicional, la referencia al objeto this se pierde, por lo que tendremos que hacer uso del método bind como se muestra a continuación:

<input name="firstName" type="text" className="form-control" onChange={this.handleChange.bind(this)}/>

Pienso que es más común inicializar los estados en el constructor de la clase. Así es como también aparece en la documentación oficial.

    constructor(props){
        super(props);
        this.state = {
           email: '',
           firstName: '',
        };
    }

Resumen

Para manejar los valores de nuestros inputs:

  1. A nuestros inputs, en la función handleChange, le ponemos:
this.setState({
            [e.target.name]: e.target.value,
        })
para que cree una variable por cada input
  1. A nuestros inputs les ponemos valor:
value={this.state.varName}
para que no se almacene 2 veces
  1. Inicializamos una variable state al inicio de nuestro componente:
state = {
        varName: '',
        varName2: '',
    };

Opcionalmente, pero Recomendadamente, en nuestro método de handleSubmit, podemos manejar los datos, los cuales están almacenados en this.state

En esta clase vimos como Richard inicializa el state dentro de la clase sin necesidad de escribir un constructor, lo cual hizo que me preguntara el por qué, así que después de buscar pude encontrar una lectura acerca de en dónde inicializar el estado, la cual dejaré aquí

Hola, les comparto el mismo código, pero usando Hooks:

import React, {useState} from 'react';

const BadgeForm = () => {

    const [formData,setFormData] = useState({})

    const handleChange = (e)=>{
        setFormData({...formData,[e.target.name]:e.target.value})
    }

    const handleClick = (e)=>{
        console.log("button pressed");
    }

    const handleSubmit = (e)=>{
        e.preventDefault();
        console.log(formData)
    }

    return ( 
        <div>
            <h1>New Attendant</h1>
            <form onSubmit={handleSubmit}> 
                <div className="form-group">
                    <label>First Name</label>
                    <input value={formData.first_name} onChange={handleChange} className="form-control" type="text" name="first_name"></input>
                </div>

                <div className="form-group">
                    <label>Last Name</label>
                    <input value={formData.last_name} onChange={handleChange} className="form-control" type="text" name="last_name"></input>
                </div>

                <div className="form-group">
                    <label>Email</label>
                    <input value={formData.email} onChange={handleChange} className="form-control" type="email" name="email"></input>
                </div>

                <div className="form-group">
                    <label>Job Title</label>
                    <input value={formData.job_title} onChange={handleChange} className="form-control" type="text" name="job_title"></input>
                </div>

                <div className="form-group">
                    <label>Twitter</label>
                    <input value={formData.tiwtter} onChange={handleChange} className="form-control" type="text" name="twitter"></input>
                </div>


                <button  onClick={handleClick} className="btn btn-primary">Save</button>
            </form>
        </div>
     );
}
 
export default BadgeForm;

Sigo diciendo que ya es hora de actualizar el curso.

hay alguna forma de ver la memoria que se ocupa al no controlar los inputs y setear el state (datos duplicados) y al controlar los inputs (única copia de datos)?

Si por alli alguien no entendio la magia de :

Aqui les dejo un link, https://stackoverflow.com/questions/11508463/javascript-set-object-key-by-variable

Es brutal la elegancia de codigo al usar esto!!
Buena @esparragus !!

para declarar una variable como key del set state es necesario escribirla entre corchetes cuadrados

handleChange = e => {
    this.setState({
      [e.target.name]: e.target.value
    });
  };```

Hahahah Gusta los pines!!! en cada video.

Hola, les dejo un Repositorio con mi avance del curso y notas personales =)

Me agrada mucho este profesor.

Necesito pegar esto en mi cuarto:
-Copiar
-Pegar
-Reemplazar
-Repetir

el complemento o plugin ya no funciona como se muestra en el ejemplo

Aun no entiendo muy bien por que sale ese warning

Muy bien explicado de como funciona el estado en React, es espectacular los detalles que cuenta el profesor y el porque pasa y como se debe de hacer para solucionar dichos problemas

  • Para guardar la información en el estado se usa una función de la clase component llamada setState a la cual se le debe pasar un objeto con la información que se quiere guardar.

  • Aunque no se ve, la información está siendo guardada en dos sitios. Cada input guarda su propio valor y al tiempo la está guardando en setState, lo cual no es ideal. Para solucionarlo hay que modificar los inputs de un estado de no controlados a controlados.

Apuntes de la clase:

Espero les sriva…

Que irónico que en el curso de react haya tantos problemas con la sincronización entre la parte de discuciones y los videos. Estoy viendo un video y la parte de discuciones e incluso el titulo pertenecen a otro.

teacher … seria bueno q menciones , cuales son las teclas q usas para x ejemplo los comentarios o para organizar … los shortcuts de vs code…!!
Gracias!

Richard excelente clase, la verdad explicas de una manera muy sencilla lo del manejo del estado, cuando trate de real izarlo apara un proyecto en el bootcam en el que estoy me tarde mas de una semana y sin comprender lo tan bien como hasta ahora.

Solucioné el error en consola al editar los campos de texto, modificando lo siguiente en el class BadgeForm

state = {
    firstName: "",
    lastName: "",
    heroClass: "",
    faction: "",
    whyIsHere: ""
  }; ```

Saludos
<h1>Manejo de estado</h1>

La manera en la que maneja un componente su propia información es mediante la generación del estado, mismo que un componente de tipo clase lo maneja en this.state y los componentes de tipo función mediante el hook useState.

Los estados son variables que pueden acceder el componente, mismas que se van modificando conforme lo necesite,

Un uso muy común es modificar el estado local para pasar props a componentes hijos de manera que éstos puedan renderizar la información que se le pase, aunque puedes realizar cualquier lógica necesaria como si fuera una variable local

Una limitación del estado es que no se puede asignar valores de manera directa, necesitas hacer uso de la función del componente (o del hook useState) setState, mismo que guarda en el estado el objeto que se le pase como argumento this.setState({newState: state})

class Button extends React.Component {
  state = { count: 0 }

  handleClick = () => (
     this.setState({ count: this.state.count + 1 })
  );

  render() {
    const { count } = this.state;

    return (
      <div>
        <h1>Manzanas: {count}</h1>
        <button onClick{this.handleClick}>Sumar</button>
      </div>
    );
  }
}

por ahora creo que el contenido está dado mas conciso que el curso hecho por Leonidas, eso hace que tenga una curva de aprendizaje mas apropiada para recién iniciados en react, sin tanto babel, webpack, patrones y buenas practicas, etc… que son mas “decorados” en términos teóricos (porque en la practica son obligatorios se podría decir)

Por si alguien lo esta haciendo con hooks

    const [valuesForm, setValuesForm] = useState({
        firstName: '',
        lastName: '',
        jobTitle: '',
        email: '',
        twitter: '',
    })

    const { firstName, lastName, jobTitle, email, twitter } = valuesForm

    const handleChange = (e) => {
        setValuesForm({
            ...valuesForm,
            [e.target.name]: e.target.value
        })
    }

    const handleSubmit = (e) => {
        e.preventDefault()
        console.log(valuesForm);
    }```

BadgeFrom

import React, { Component } from 'react';

class BadgeForm extends Component {
  state = {
    firstName: '',
    lastName: '',
    email: '',
    jobTitle: '',
    twitter: ''
  }
  handleChange = e => {
    // console.log({
    //  value: e.target.value,
    //  name: e.target.name
    // })
    this.setState({
      [e.target.name]: e.target.value
    })
  }

  handleClick = e => {
    console.log("click")
  }

  handleSubmit = e => {
    e.preventDefault()
    console.log("Form")
    console.log(this.state)
  }
  
  render() {
    return (
      <div>
        <h1>Nuevo asistente</h1>
        <form onSubmit={this.handleSubmit}>
          <div className="form-group">
            <label>Nombre</label>
            <input 
              onChange={this.handleChange} 
              className="form-control" 
              type="text" 
              name="firstName" 
              value={this.state.firstName}
            />
          </div>

          <div className="form-group">
            <label>Apellido</label>
            <input 
              onChange={this.handleChange} 
              className="form-control" 
              type="text" 
              name="lastName"
              value={this.state.lastName}
            />
          </div>

          <div className="form-group">
            <label>Email</label>
            <input 
              onChange={this.handleChange} 
              className="form-control" 
              type="email" 
              name="email"
              value={this.state.email}
            />
          </div>

          <div className="form-group">
            <label>Ocupación</label>
            <input 
              onChange={this.handleChange} 
              className="form-control" 
              type="text" 
              name="jobTitle"
              value={this.state.jobTitle}
            />
          </div>

          <div className="form-group">
            <label>Twitter</label>
            <input 
              onChange={this.handleChange} 
              className="form-control" 
              type="text" 
              name="twitter"
              value={this.state.twitter}
            />
          </div>

          <button onClick={this.handleClick} className="btn btn-primary">Guardar</button>
        </form>
      </div>
    )
  }
}

export default BadgeForm;

Que buena explicacion de React excelente profesor…muy practico

  • Manejo de Estado.
    • Para guardar la información en el estado se usa una función de la clase component llamada setState a la cual se le debe pasar un objeto con la información que se quiere guardar.
    • Cada input guarda su propio valor y al tiempo la está guardando en setState, lo cual no es ideal. Para solucionarlo hay que modificar los inputs de un estado de no controlados a controlados. como se hace eso al imput se le pasa el valor example:
	<input
              onChange={this.handleChange}
              className="form-control"
              type="text"
              name="lastName"
              value={this.state.lastName}
           />

El estado siempre se debe inicializar

Entonces es importante recordar que al manejar estados con inputs es recomendable asociarlo al estado mediante:

<input value={this.state.elNombre}/>

Este sería mi componente de login con su respectivo estado agregue error para validación del usuario si escribe un campo con requerimientos faltantes.

Estoy flipando D:

Excelente

Me ha gustado mucho esté curso, he aprendido mucho!!

Alguien sabe a qué se debe el warning que aparece en consola?

Uno de los mejores profesores de platzi , soy arquitecto angular y ionic y no era muy fan de react pero este profesor esta 5 estrellas

Esta informacion se esta guardando en dos sitios, cada input guarda su propio valor, y ademas le esta diciendo al setState guarda este valor. No queremos eso. Para eso tenemos que cambiar nuestros inputs de no controlados a controlados. Agregando el props de value

El profesor explica muy bien, lo únioc el error de la consola, pero se soluciona inicializando todo los valores de los input como vacios.

Una pequeña corrección que hará una gran diferencia en los usuarios con discapacidad visual:
A la hora de utilizar el tag <label> deberíamos insertar el input como un elemento hijo de este (creo que es la forma más práctica en React), de esta forma hacemos que los lectores de pantalla lean el label en cuestión y la persona que este utilizando su web pueda saber de que trata en input en cuestión.
Ejemplo:

<div className="form-group">
          <label>
            First name
            <input
              onChange={handleChange}
              className="form-control"
              type="text"
              name="firstName"
              value={formData.firstName}
            />
          </label>
        </div>```

Los invito a activar el voice over en sus equipos y escuchar  la diferencia (command + f5 en mac)

Hola profe: tengo una pregunta
me confunde la manera en que se debe inicializar “state = {}” y no "this.state.firstName = ‘’ "
gracias

Hay una forma que los componentes pueden producir su propia informacion y guardarla, para consumirla o para pasarla a otros componentes atravez de sus props. La clave esta en que la informacion del estado pase en una sola direccion y otros props la pueden consumir y utilizar pero no cambiar.

Para guardar la informacion, utilizamos una funcion de la clase component, donde hacemos un objeto con las opcionnes que queremos guardar.

Esto seria:

handleChange = (e) => {
    this.setState({
      firstName: e.target.value,
    });
  };

El problema es que ahora cada input que guardemos sera de nombre fristname, para poder guardarlo en diferentes espacios. Para poder hacer esto haremos sera mandarle un arreglo donde le diremos sque se guarde en cada variable dependiendo de su nombre con:

handleChange = (e) => {
    this.setState({
      [e.target.name]: e.target.value,
    });
  };

El problema de esta forma es que la informacion termina guardada en dos sitios y eso cuando una aplicacion crece empieza a representar un problema. Porque cada input empieza a guardar su propio valor y aparte le esta diciendo a setState que tambien lo haga, esto no es ideal. Es mejor tener una sola fuente de informacion.

Para poder arreglar esto, es mejor cambiar los inputs a NO CONTROLADOS a CONTROLADOS. Para poder hacer esto, tenemos que pasarle un PROP adicional que es el ‘value’. Tenemos que leer el estado de la siguiente forma:

value={this.state.nombreInput}

Pero esto nos ocacionara un error, donde nos dice que estos valores de STATE no estan inicializados, para hacerlo en cualquier linea o preferiblemente la primera, tenemos que poner:

state ={};

Ahora al hacer el submite no leeiamos los valores, ya podemos hacerlo con un simple console.log e imprimiendo el estado.

Cómo asignar nombres dinámicos a las propiedades.

Cuando se tiene que imprimir por consola muchos datos y se hace un poco dificil su lectura pueden utilizar ** console.table () **, el cual va a agrupar todos los elementos y mostrarlos mucho mejor.

Ejemplo:

Por si quieren que su editor les acomode el codigo automaticamente he dejado un pequeño tutorial para hacerlo con prettier

se recomienda que todos los valores de las propiedades del objeto state siempre sean string?

this.setState({
[e.target.name]: e.target.value
});

Encontré esta hermosura de definición en el foro:

Estado

Primero hay que entender que los estados pertenecen a los componentes.

El estado es similar a las props. Pero éste es privado.

Privado significa que un componente podrá modificar su estado pero no el de otro componente.
Solo disponible para su componente.

Tanto los state como los props, son objetos planos en JavaScript. Pero se diferencian en algo:

  • Los props se pasan al componente como cuando pasamos parámetros a una función.
  • El state no se pasa, este se administra dentro del componente. Como las variables declaradas dentro de una función. Este vive dentro del componente desde un inicio.
  • El state tiene un valor predeterminado cuando se monta el componente.

Luego sufre cambios con el tiempo, normalmente con eventos que activa el usuario. Entonces, se podría decir que el estado es una representación de su componente porque contiene los datos que representan un componente.

Cuándo un componente tendrá estado y cuando no?

Tendrá estado cuando el componente recibe información para cambiar algún elemento dentro de el.
Cuando el componente es prestacional, no necesitaría estado.

Fuente

Si alguien noto el error que arroja en la consola, se refiera que se esta tratando de controlar un elemento con un valor que aun no existe.
Si bien inicializamos el state como un objeto vació, pero las propiedades del estado aun no.
La inicialización pudiera ser de esta forma.

state = {
        firstName:'',
        lastName:'',
        email:'',
        jobTitle:'Designer',
        twitter:''
    }

Depronto a alguien le pasa como a mi, que el state no se esta cargando mas que el jobTitle como en el ejemplo y a su vez no me es posible modificar el contenido del jobTitle, cada vez que lo cambio se restablece por defecto al que se le definio en el ejemplo, sin embargo a el profesor si le permite hacer el cambio luego de establecido

Cómo setear nombre de propiedad dinámicamente

No se si será por la actualización de React que ya no es igual a lo que se muestra en este video, pero cuando escribo en el formulario, como lo hace el profesor en el minuto 2:33 no veo ningún “state” actuálizandose. Alguien sabe si en la actualidad este ejemplo funciona igual? Saludos.

¿Cuál es la diferencia entre state y props?
props (abreviatura de ”properties”) y state son objetos planos de JavaScript. Mientras ambos contienen información que influye en el resultado del render, son diferentes debido a una importante razón: props se pasa al componente (similar a los parámetros de una función) mientras que state se administra dentro del componente (similar a las variables declaradas dentro de una función).

Al utilizar componentes como funciones en lugar de clases, se utilizan los "React Hooks", que en cierto modo resultan ser más sencillos de manejar que el estado en una clase ya que puedes separar diferentes valores en diferentes variables. Las funciones componente y los hooks lucen así: ''' function Component(props) { [firstname, setFirstname] = React.useState(); [lastname, setLastname] = React.useState(); return ( <form> <input value={firstname} onChange={e => setFirstname(e.target.value)} /> <input value={lastname} onChange={e => setLastname(e.target.value)} /> </form> ); } '''

Creo que podemos mejorarlo haciendo un componente de input para nuestro formulario y lo reutilizamos, asi nos queda mas legible el codigo del form

a alguien mas le pasa que hay veces que cuando terminas la clase y esperas los 3 segundo para ir a la clase siguiente, el contador empieza a arrojar valores negativos infinitamente y nunca avanza a la siguiente clase ???

A cerca de loc omponentes controlados que menciona:

A Controlled Component is one that takes its current value through props and notifies changes through callbacks like onChange. A parent component “controls” it by handling the callback and managing its own state and passing the new values as props to the controlled component. You could also call this a “dumb component”.

A Uncontrolled Component is one that stores its own state internally, and you query the DOM using a ref to find its current value when you need it. This is a bit more like traditional HTML.

//Todo eso sería más fácil con spread operator (los tres puntos)

state= {
email: ’ ',
firstName: ’ '
}

handleChange = e => {
this.setState({
…state,
[e.target.name]: e.target.value
});
}

el warning que apareció en el final, como lo podemos fixear?

Excelente explicación

Excelente clase!!!

a seguir aprendiendo!

Que genial tuvo esta clase!!

![](

Mi código hasta ahora:

import React, { useState } from 'react';

const BadgeForm = () => {
    const [firstName, setFirstName] = useState('');
    const [lastName, setLastName] = useState('');
    const [email, setEmail] = useState('');
    const [jobTitle, setJobTitle] = useState('');
    const [twitter, setTwitter] = useState('');

    return(
        <div>
            <h1>New Attendant</h1>
            <form>
                <div className="form-group">
                    <label>First Name</label>
                    <input
                        onChange={(e) => setFirstName(e.target.value)}
                        className="form-control"
                        type="text"
                        name="firstName"
                        value={firstName}
                    />
                </div>
                <div className="form-group">
                    <label>Last Name</label>
                    <input
                        onChange={(e) => setLastName(e.target.value)}
                        className="form-control"
                        type="text"
                        name="lastName"
                        value={lastName}
                    />
                </div>
                <div className="form-group">
                    <label>Email</label>
                    <input
                        onChange={(e) => setEmail(e.target.value)}
                        className="form-control"
                        type="email"
                        name="email"
                        value={email}    
                    />
                </div>
                <div className="form-group">
                    <label>Job Title</label>
                    <input
                        onChange={(e) => setJobTitle(e.target.value)}
                        className="form-control"
                        type="text"
                        name="jobTitle"
                        value={jobTitle}   
                    />
                </div>
                <div className="form-group">
                    <label>Twitter</label>
                    <input
                        onChange={(e) => setTwitter(e.target.value)}
                        className="form-control"
                        type="text"
                        name="twitter"
                        value={twitter}
                    />
                </div>
                <button onClick={(e) => {e.preventDefault(); console.log('Button was clicked')}} className="btn btn-primary">Save</button>
            </form>
        </div>
    )
}

export default BadgeForm;

Así se vería un ejemplo utilizando el hook useState en un componente funcional.
.

import React, {useState} from 'react'

const Button = (props) => {
	const [count, setCount] = useState(0)
  handleClick = (event) => {
		event.preventDefault()
    setCount(count+1)
  }
  return (
    <div>
			<h1>Manzanas: {count}</h1>
			<button onClick={handleClick}>Sumar</button>
		</div>
  );
}

.
Donde:

  • Desestructuramos las variables count y setCount desde un estado inicializado con 0.
  • count: será utilizado en nuestra aplicación como el estado local de sólo lectura
  • setCount: es el método con el que podremos asignar nuestro estado, podemos asignarlo con cualquier cosa, pero para este caso utilizaremos enteros.
  • useState: hook para manejar el evento.
  • onClick: Es el manejador del evento click
  • handleClick: Es el callback donde manejamos la lógica del evento

No entiendo que es lo que cambia al final agregando el atributo value a cada uno de los campos del formulario, si ya con el setState se asignaba el valor automaticamente a medida que uno iba escribiendo.

Para pasar de Componentes no Controlados a Componentes Controlados se debe usar value en cada uno de los inputs.

Porque ReactJS tiene que almacenar en “state” el valor de los inputs, cuando, en JQuery con solo usar $(input).val(); obtenias el valor del input direcatamente sin almacenar en ningun lado previamente.

Por qué no es ideal tener dos veces la info?

Esto de los estados debe ser la piedra angular de react

Según lo que investigué y entendí. Lo que queremos conseguir al controlar el estado del input es que no se repita el valor del mencionado en el virtual DOM de react y en HTML plano. Queremos que react sea la única fuente de la verdad. Por eso añadimos la propiedad value al input. Como recordaremos, en HTML plano, ésta propiedad nos permite darle un valor predeterminado al input, y lo que hacemos aquí es indicarle que el valor predeterminado será la propiedad del objeto state que le asignemos a un input.

dicha propiedad puede ser name cómo el ejemplo de arriba.
Recordemos también que para que Ract no caiga en un error de no saber si el componente es controlado o no controlado tenemos que declarar el objeto state con las propiedades equivalentes a los nombres de los inputs cómo strings vacíos.
Los cuales van a ser llenados al momento que se active el evento onChange.

Fuente:https://www.youtube.com/watch?v=7FQS6_fOgR8

La manera correcta de agregar el state es en el constructor(), ya que es ahi en donde se va a almacenar en memoria toda la informacion que necesita el componente para vivir. Eso se hace de la siguiente manera:

class BadgeForm extends React.Component{
  constructor(props){
    super(props)
    this.state = {value: ""}

    this.handleChange.bind(this)
    this.handleSubmit.bind(this)
  }

  handleChange = e => {
    @code
  }

  handleSubmit = e => {
    @code
  }

  render(){
    @code
  }
}

https://reactjs.org/docs/forms.html#controlled-components

Tratando de encontrar un símil:

Props: es el genotipo.

State: es el Fenotipo.

🤣

Props VS State

“En un componente de React, las props son variables que le pasa su componente principal. Por otro lado, el estado sigue siendo variable, pero directamente inicializado y administrado por el componente”

  • Las propiedades o props son externas al componente, se configuran y se modifican desde el padre, y nunca desde el mismo componente.

  • El **estado o state **es interno del componente, se configuran en la constructor y se modifican desde el mismo componente, usando this.setState(). Recuerda que no debemos modificar los valores del estado directamente.

/ Fuente:

Eventos Enlazados

Se me ocurrió hacer una pequeña ilustración en Figma para hacerlo un poco más descriptivo, espero a alguien más le funcione.
A mi me ayudó a comprender de manera gráfica el funcionamiento de los Eventos Enlazados.
⠀⠀⠀
Greetings!
⠀⠀⠀

Les dejo algunos puntos clave que me llevo de esta clase:

//inicializar el estado con un objeto vacío al inicio del componente
state = {}

//función serState
this.setState({
      [e.target.name]: e.target.value
    })


//inputs
//state.value es lo que hace que el input tenga estado controlado
<div className="form-group">
          <label>First Name</label>
          <input 
							onChange={this.handleChange} 
							className="form-control" 
							type="text" 
							name="firstName" 
							value={this.state.firstName}
					/>
        </div>

Error, inicializar State

setState

la herramienta de react devtools a cambiado un poco pero mantiene las mismas caracteristicas

si ves esto después del 7 de mayo del 2021: react actualizo sus developer tools y ahora los promps y states estan en la pestaña components-nombre del componente 😃

Vamos muy bien Richard.

Hola, consulta técnica. Esto del this.state por supuesto que está bueno saberlo por si te encontrás con eso, pero con los hooks ya pasó a la historia? o hay algo que this.state pueda hacer que los hooks no?
Gracias People()!

Para solucionar tambien el error que menciona @ErikOchoa también pueden usar declarar las funciones en el constructor.

Un ejemplo

 constructor(props){
    super(props);
    this.state = {
      email: '',
      firstName: '',
      lastName: ''
    };

    this.handleChange = this.handleChange.bind(this);
    this.handleClick = this.handleClick.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

Genial, no sabía que se podían guardar datos.

Wuuaooo esto es muy interesante… me tiene curiosa. 😉

buenas clases

Cómo corregir el warning del final ? Me fastidia.

Dentro de VSCode en el menú Help – Keyboard Shortcuts Reference bajas el listado completo

Oigan, puedo pedir algo? me gustaria tener un plugin para correr esto a x3 velocidad (la competencia lo tiene). Ayudaria mucho para repasar

Excelente

Genial!! me toma el triple de tiempo este curso clase a clase seguir y practicar, pero vale la pena!

me esta gustando como esta quedando esta pagina

Woow

Con los estados todo queda mas controlado!

Hola chicos, pregunta: Solo me aparece en console el evento de “Button was clicked” pero no me aparece el de “Form was submitted” ya me asesore de revisar bien el codigo y tiene su respectivo onSubmit={this.handleSubmit}, alguno de ustedes me podra colaborar en decirme que puede suceder?. Gracias.

El error que le sale al maestro en consola

de que es? no es nada relevante?

a mi tambien me sale

Hola amigos, para los que quieren saber más sobre la Genial asignación que realizarlo profe this.setState({[e.target.name]:e.target.value}), esto es posible gracias a ES6 Computed Property name en los objetos literales.