Tengo el siguiente componente React:
export default class MyComponent extends React.Component {
onSubmit(e) {
e.preventDefault();
var title = this.title;
console.log(title);
}
render(){
return (
...
<form className="form-horizontal">
...
<input type="text" className="form-control" ref={(c) => this.title = c} name="title" />
...
</form>
...
<button type="button" onClick={this.onSubmit} className="btn">Save</button>
...
);
}
};
La consola me está dando, ¿ undefined
alguna idea de lo que está mal con este código?
javascript
reactjs
JoeTidee
fuente
fuente
this.onSubmit.bind(this);
e.target.value
sin la atadura?onSubmit
método al botón de envío (elemento DOM) al hacer clic (es decironClick={this.onSubmit.bind(this)}
). Y si desea acceder al valor de la entrada del título en el formulario que puede usaronSubmit(event) { const title = event.target.elements.title.value; }
.Respuestas:
Debe usar el constructor bajo la clase MyComponent extiende React.Component
Entonces obtendrás el resultado del título
fuente
Aquí hay tres respuestas, dependiendo de la versión de React con la que estés (forzado) a trabajar (ing) y de si quieres usar ganchos.
Lo primero es lo primero:
Es importante entender cómo reaccionan los trabajos, por lo que puede hacer las cosas bien (protip: es es súper pena correr a través de la Reaccionar ejercicio tutorial en el sitio web Reaccionar Está bien escrito, y cubre todos los aspectos básicos de una manera que explica realmente cómo hacerlo. cosas). "Correctamente" aquí significa que está escribiendo una interfaz de aplicación que se representa en un navegador; todo el trabajo de interfaz ocurre en React, no en "a lo que estás acostumbrado si estás escribiendo una página web" (es por eso que las aplicaciones React son "aplicaciones", no "páginas web").
Las aplicaciones de reacción se representan en base a dos cosas:
Lo que está expresamente no hacerlo cuando utiliza Reaccionar está generando elementos HTML y luego usando los: cuando le dices a reaccionar a utilizar una
<input>
, por ejemplo, que está no crear un elemento de entrada HTML, le está diciendo reaccionan para crear un objeto de entrada Reaccionar eso pasa a representarse como un elemento de entrada HTML, y cuyo manejo de eventos observa, pero no está controlado por , los eventos de entrada del elemento HTML.Cuando usa React, lo que está haciendo es generar elementos de la interfaz de usuario de la aplicación que presenten al usuario datos (a menudo manipulables), con la interacción del usuario cambiando el estado del Componente, lo que puede provocar que una parte de la interfaz de la aplicación refleje el nuevo estado. En este modelo, el estado es siempre la autoridad final, no "cualquier biblioteca de IU que se use para representarla", que en la web es el DOM del navegador. El DOM es casi una ocurrencia tardía en este modelo de programación: es solo el marco de UI particular que React está usando.
Entonces, en el caso de un elemento de entrada, la lógica es:
render
llamada después de la actualización, pero solo si la actualización de estado cambió el estado.Todo eso sucede en cuestión de milisegundos, si no menos, por lo que parece que tecleaste en el elemento de entrada de la misma manera que estás acostumbrado a "simplemente usando un elemento de entrada en una página", pero eso no es absolutamente lo que sucedió
Entonces, dicho esto, sobre cómo obtener valores de elementos en React:
Reacciona 15 y menos, con ES5
Para hacer las cosas correctamente, su componente tiene un valor de estado, que se muestra a través de un campo de entrada, y podemos actualizarlo haciendo que ese elemento de la interfaz de usuario envíe eventos de cambio nuevamente al componente:
Por lo tanto, le decimos a React que use la
updateInputValue
función para manejar la interacción del usuario, usesetState
para programar la actualización de estado, y el hecho de querender
aprovechethis.state.inputValue
significa que cuando vuelve a funcionar después de actualizar el estado, el usuario verá el texto de actualización en función de lo que escribió.Anexo basado en comentarios
Dado que las entradas de la IU representan valores de estado (considere lo que sucede si un usuario cierra su pestaña a mitad de camino y la pestaña se restaura. ¿Deberían restaurarse todos esos valores que completaron? Si es así, ese es el estado). Eso podría hacerte sentir que un formulario grande necesita decenas o incluso cien formularios de entrada, pero React se trata de modelar tu IU de una manera sostenible: no tienes 100 campos de entrada independientes, tienes grupos de entradas relacionadas, por lo que capturas cada uno agrupe en un componente y luego cree su formulario "maestro" como una colección de grupos.
Esto también es mucho más fácil de mantener que un componente gigante de forma única. Divida los grupos en Componentes con mantenimiento de estado, donde cada componente solo es responsable de rastrear algunos campos de entrada a la vez.
También puede sentir que es "una molestia" escribir todo ese código, pero eso es un falso ahorro: los desarrolladores que no son usted, incluido el futuro, realmente se benefician enormemente al ver todas esas entradas conectadas explícitamente, porque hace que las rutas de código sean mucho más fáciles de rastrear. Sin embargo, siempre puedes optimizar. Por ejemplo, puedes escribir un enlazador de estado
Por supuesto, hay versiones mejoradas de esto, así que visite https://npmjs.com y busque la solución de enlace de estado React que más le guste. El código abierto se trata principalmente de encontrar lo que otros ya han hecho y usarlo en lugar de escribir todo usted mismo desde cero.
Reacciona 16 (y 15.5 de transición) y JS 'moderno'
A partir de React 16 (y de inicio suave con 15.5), la
createClass
llamada ya no es compatible y es necesario utilizar la sintaxis de clase. Esto cambia dos cosas: la sintaxis de clase obvia, pero también elthis
enlace de contexto que secreateClass
puede hacer "gratis", así que para asegurarse de que las cosas sigan funcionando, asegúrese de estar usando la notación de "flecha gruesa" para elthis
contexto que conserva funciones anónimas en losonWhatever
controladores, como laonChange
usamos en el código aquí:También es posible que haya visto a personas usar
bind
en su constructor para todas sus funciones de manejo de eventos, como esta:No hagas eso.
Casi cada vez que está usando
bind
, se aplica el proverbial "lo estás haciendo mal". Su clase ya define el prototipo del objeto y, por lo tanto, ya define el contexto de la instancia. No pongasbind
encima de eso; use el reenvío de eventos normal en lugar de duplicar todas sus llamadas de función en el constructor, porque esa duplicación aumenta la superficie de su error y hace que sea mucho más difícil rastrear errores porque el problema podría estar en su constructor en lugar de donde llama su código. Además de imponer una carga de mantenimiento a otros con los que usted (tiene o elige) trabajar.Sí, sé que los documentos de reacción dicen que está bien. No lo es, no lo hagas.
Reacciona 16.8, usando componentes de función con ganchos
A partir de React 16.8, el componente de función (es decir, literalmente solo una función que toma algo
props
como argumento se puede usar como si fuera una instancia de una clase de componente, sin escribir nunca una clase) también se le puede dar estado, mediante el uso de ganchos .Si no necesita un código de clase completo, y una función de instancia única servirá, ahora puede usar el
useState
enlace para obtener una sola variable de estado y su función de actualización, que funciona más o menos igual que los ejemplos anteriores, excepto sin lasetState
llamada a la función:Anteriormente, la distinción no oficial entre las clases y los componentes de la función era "los componentes de la función no tienen estado", por lo que ya no podemos escondernos detrás de eso: la diferencia entre los componentes de la función y los componentes de las clases se puede encontrar en varias páginas muy bien. documentación de reacción escrita (sin acceso directo, una explicación de línea para malinterpretar convenientemente para usted) que debe leer para saber lo que está haciendo y así saber si eligió la mejor solución (lo que sea que eso signifique para usted) para programarlo usted mismo por un problema que tienes
fuente
Logramos obtener el valor del campo de entrada haciendo algo como esto:
fuente
En reaccionar 16, yo uso
fuente
Logré hacerlo vinculando el "this" a la función updateInputValue (evt) con
this.updateInputValue = this.updateInputValue.bind (this);
Sin embargo, el valor de entrada = {this.state.inputValue} ... resultó no ser una buena idea.
Aquí está el código completo en babel ES6:
fuente
su error se debe a que usa class y cuando usa class necesitamos vincular las funciones con This para que funcione bien. de todos modos hay muchos tutoriales sobre por qué deberíamos "esto" y qué es "esto" hacer en javascript.
si corrige su botón de envío, debería funcionar:
y también si desea mostrar el valor de esa entrada en la consola, debe usar var title = this.title.value;
fuente
Dale
<input>
una identificación únicay luego use la API web estándar para referenciarla en el DOM
No es necesario actualizar continuamente el estado Reaccionar con cada pulsación de tecla. Simplemente obtenga el valor cuando sea necesario.
fuente
fuente
Puede obtener un valor de entrada sin agregar la función 'onChange'.
Simplemente agregue al elemento de entrada un 'ref attr:
Y luego use this.refs para obtener el valor de entrada cuando lo necesite.
fuente
Cambie su referencia a:
ref='title'
y eliminename='title'
Luego eliminevar title = this.title
y escriba:También deberías agregar
.bind(this)
athis.onSubmit
(Funcionó en mi caso que era bastante similar, pero en lugar de
onClick
que teníaonSubmit={...}
y se puso en la forma (<form onSubmit={...} ></form>)
)fuente
si usa el componente de clase, entonces solo 3 pasos: primero debe declarar el estado de su entrada archivada, por ejemplo this.state = {name: ''} . En segundo lugar, debe escribir una función para establecer el estado cuando cambia en el siguiente ejemplo, es setName () y finalmente debe escribir la entrada jsx por ejemplo <input value = {this.name} onChange = {this.setName} />
fuente
fuente
utilizando campos no controlados:
fuente