Reaccione cuatro formas de vincular eventos desde componentes controlados por eventos y componentes no controlados

1. Introducción

El manejo de eventos de los elementos React es similar a los elementos DOM. Pero hay una pequeña diferencia sintáctica:

  • Las propiedades de enlace del evento React se denominanCaja de camello, En lugar de minúsculas, por ejemplo, los eventos nativos son todos en minúsculas onclick, y los eventos en React son joroba en Click.
  • Si se requiere la sintaxis JSXPase una función como controlador de eventos, En lugar de una cadena (cómo se escriben los elementos DOM).
  • Los eventos de reacción no son eventos nativos, sino eventos sintéticos.
  • Otra diferencia en React es que no puede evitar un comportamiento falso devolviendo false. Debe usar explícitamente e.preventDefault ().

HTML generalmente se escribe como:

<button onclick="clickHandle()">提交</button>

<script>
function clickHandle(e){
	e.preventDefault();	//阻止默认事件
	//或者使用如下的写法
	return false;
}
</script>

La redacción en React es:

<button onClick={clickHandle}>提交</button>

<script>
function clickHandle(e){
	e.preventDefault();	//阻止默认事件,不能使用return false
}
</script>

2. Varias formas para que React enlace eventos

  • Cuando se usa la sintaxis de clase ES6 para definir un componente, el controlador de eventos se convierte en un método de la clase.
  • Debe tener cuidado con esto en la función de devolución de llamada JSX. Los métodos de la clase no lo vincularán de forma predeterminada. Si olvida vincular this.handleClick y pasarlo a onClick, el valor de esto será indefinido cuando llame a esta función.
  • Normalmente, si no agrega () después del método, por ejemplo onClick = {this.handleClick}, debe vincular esto a este método.

2.1 Método uno

Use la función de flecha en la función de devolución de llamada y escriba directamente la función de flecha en línea en render () (no recomendado) . El problema con este método es que se crea una función de devolución de llamada diferente cada vez que se ejecuta render (). En la mayoría de los casos, esto no es problema. Sin embargo, si esta función de devolución de llamada se pasa como un valor de propiedad a los componentes de bajo nivel, estos componentes se pueden volver a representar adicionalmente.

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class Box extends Component {
  handleClick(e,val){
  	console.log(e,val);
  }
  render() {
    return (
      <button onClick={(e)=>this.handleClick(e,'aa')}>添加</button>
    );
  }
}

ReactDOM.render(
  <Box />,
  document.getElementById('root')
);

2.2 Método dos

En el método render (), use bind para vincular esto (no recomendado) . Defina una función que no sea una flecha directamente en el componente y luego úsela directamente en el renderizado. onClick={this.handleClick.bind(this)}La desventaja de este método es que cada vez que use bind para vincular esto, el código será redundante:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class Box extends Component {
	handleClick(val,e) {	//事件对象e要放在最后
		console.log(val,e);
	}
	render() {
		return (
			<button onClick={this.handleClick.bind(this, 'aa')}>添加</button>
		);
	}
}

ReactDOM.render(
  <Box />,
  document.getElementById('root')
);

2.3 Método tres

Use el inicializador de propiedades para enlazar correctamente la función de devolución de llamada (recomendado) , y use la función de flecha para definir un método en el componente. La desventaja de este método es que no puede personalizar el parámetro:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class Box extends Component {
	handleClick =(e)=>{
		console.log(e);
	}
	render() {
		return (
			<button onClick={this.handleClick}>添加</button>
		);
	}
}

ReactDOM.render(
  <Box />,
  document.getElementById('root')
);

2.4 Método 4

Defina un método de una función que no sea una flecha directamente en el componente, y luego enlace (esto) (recomendado) en el constructor. La ventaja de este método es que el rendimiento es mejor. No importa cuántas veces se ejecute render (), eventualmente apunta a la misma referencia. La desventaja de este método es que no puede personalizar los parámetros.

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class Box extends Component {
	constructor(){
		super();
		this.myhandleClick = this.handleClick.bind(this);
	}
	handleClick(e){
		console.log(e);
	}
	render() {
		return (
			<button onClick={this.myhandleClick}>添加</button>
		);
	}
}

ReactDOM.render(
  <Box />,
  document.getElementById('root')
);

3. Reaccione el parámetro del evento

Al igual que los navegadores normales, el evento handleClick se pasará automáticamente a un objeto de evento, que contiene básicamente los mismos métodos y propiedades que el objeto de evento del navegador normal. Reaccionar diferencia es que los eventobjetos no son proporcionados por el navegador, pero su propio construido interna. También tiene event.stopPropagation, event.preventDefaulttal método convencional.

Pase parámetros adicionales para el controlador de eventos, generalmente utilizando los dos métodos (2.1, 2.2) anteriores, a saber:

<button onClick={(e)=>this.handleClick(e, 'aa')}>添加</button>
<button onClick={this.handleClick.bind(this, 'aa')}>添加</button>

Vale la pena señalar que al pasar parámetros a la función de escucha a través del método de vinculación, la función de escucha definida en el componente de clase, el objeto de evento e debe organizarse después del parámetro pasado.

3.1 Modificar parámetros en subcomponentes

Modifique los parámetros pasados ​​por el componente primario en el componente secundario. El método más recomendado es definir el método en el componente primario, llamar al método del componente primario propsen el componente secundario, pasarlo al componente secundario y luego this.props.methodllamarlo al componente secundario . Vea el siguiente ejemplo:

Código en subcomponentes:

class Button extends Component {
  handleClick(){
  	//执行DOM元素的 change属性
    this.props.change();
  }
  render() {
    return (
     <button onClick={()=>this.handleClick()}>
       {this.props.children}
     </button>
    );
  }
}

Código en el componente principal:

class Counter extends Component {
  constructor() {
    super();
    this.state = {
      count: 0
    }
  }
  handleChange(type) {
    this.setState((preState, props) => {
          count: preState.count + 1
      } 
    }, () => { })
  }

  render() {
    return (
      <div >
        <Button change={() => this.handleChange()}>-</Button>
      </div>
    );
  }
}

4. Forma eventos

Los elementos de formulario HTML son diferentes de otros elementos DOM en React porque los elementos de formulario retienen algún estado interno desde el nacimiento.

En HTML, los elementos de formulario como <input>, <textarea> y <select> mantienen su propio estado y se actualizan según la entrada del usuario. Pero en React, el estado variable generalmente se guarda en el atributo de estado del componente y solo se puede actualizar con el método setState ().

4.1 Componentes controlados

ParaPara componentes controlados, el valor de entrada siempre se controla por el estado de React. El componente Reaccionar que procesa el formulario también controla lo que le sucede al formulario durante la entrada del usuario. Los elementos de entrada de formulario controlados por React de esta forma se denominan "componentes controlados".

Por ejemplo, si queremos que todas las letras minúsculas ingresadas por el usuario se conviertan en letras mayúsculas, podemos escribir el formulario como un componente controlado:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class Form extends Component {
  constructor() {
    super();
    this.state = {name: ""}
  }
  handleChange(event) {
    this.setState({
      name: event.target.value.toUpperCase() //	将输入的字母转成大写
    })
  }
  render() {
    return (
      <div>名称:<input type="text" value={this.state.name} onChange={this.handleChange.bind(this)} /></div>
    );
  }
}

ReactDOM.render(
  <Form />,
  document.getElementById('root')
);

Dado que el atributo de valor se establece en el elemento de formulario, entoncesEl valor mostrado siempre será this.state.value, Lo que hace que el estado de React sea la única fuente de datos. Use el evento onChange para monitorear los cambios de entrada y modificar el estado. Debido al cambio de mangoEl estado de React se ejecuta y actualiza cada vez que se presiona una tecla, Convierta las letras a mayúsculas, de modo que el valor mostrado se actualizará a medida que el usuario lo ingrese.

4.2 Elementos de entrada múltiples

  • Cuando hay varios elementos de entrada para procesar, puede pasarAgregue un atributo de nombre a cada elementoPara permitir controlador basado en event.target.nameel valor de la opción de qué hacer.
  • En React, <textarea> usa el atributo value en su lugar. De esta manera, el formulario que usa <textarea> es muy similar al formulario que usa la entrada de una sola línea.
  • En React, el menú desplegable Seleccionar no usa el atributo seleccionado, pero el atributo de valor se usa para indicar el elemento seleccionado en la etiqueta de selección raíz. Cuando Seleccionar es selección múltiple, el estado correspondiente debe ser una matriz.
  • Nota: El valor de <input type = "file"> es de solo lectura, por lo que es un componente no controlado en React.
import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class Form extends Component {
  constructor() {
    super();
    this.state = {
      name: "",
      desc: "",
      city: [1,2]
    }
  }
  handleChange(event) {
    if(event.target.name==='city'){
      this.state.city.push(event.target.value);
      this.setState({})
      return;
    }
    this.setState({
      [event.target.name]: event.target.value
    })
  }
  render() {
    return (
      <div>
        名称:<input type="text" value={this.state.name} name="name" onChange={this.handleChange.bind(this)} />
        描述:<textarea name="desc" value={this.state.desc} onChange={this.handleChange.bind(this)}></textarea>
        城市:<select name="city" multiple 
        value={this.state.city}
        onChange={this.handleChange.bind(this)}>
          <option value="1">北京</option>
          <option value="2">上海</option>
          <option value="3">天津</option>
        </select>
      </div>
    );
  }
}

ReactDOM.render(
  <Form />,
  document.getElementById('root')
);

En general, esto hace que etiquetas como <input type = "text">, <textarea> y <select> sean muy similares: todas aceptan un atributo de valor, que puede usar para implementar componentes controlados.

4.3 Escenarios de aplicación de componentes controlados.

Escenarios de aplicación de componentes controlados: puede supervisar la entrada del usuario y cambiar la entrada de datos por parte del usuario. Por ejemplo, lo anterior convertirá las letras de entrada a mayúsculas, determinará si la entrada del usuario está vacía, etc.

Si desea encontrar una solución completa que incluya validación, seguimiento de campos de acceso y procesamiento de envíos de formularios, usar Formik es una buena opción. Sin embargo, también se basa en componentes controlados y en el estado de gestión.

A veces, el uso de componentes controlados puede ser engorroso, porque necesita escribir controladores de eventos para cada forma en que cambian los datos, y pasar todo el estado de entrada a través de un componente React. En estos casos, es posible que desee utilizar componentes no controlados, que es otra forma de implementar formularios de entrada.

4.4 Componentes no controlados

Componente no controlado, el valor que muestra el componente no está completamente controlado por el estado. Use el atributo ref para enlazar a cualquier salida de componente mediante render (). Obtenga el elemento DOM vinculado a través del atributo ref, similar al uso de ref in vue.

Cómo usar ref:

Cuando el valor del atributo ref es contenido estático:
1. Vincula un atributo ref al valor de retorno de render;
2. Obtén el elemento DOM vinculado a través de this.refs;

Cuando el valor del atributo ref es state:
1. Use import para importar react.createRef;
2. Use state como el valor de atributo de ref y vincúlelo al valor de retorno de render;
3. Obtenga el elemento DOM vinculado a través de state.current;

import React, { Component,createRef } from 'react';
import ReactDOM from 'react-dom';

class Form extends Component {
  constructor() {
    super();
    this.title = createRef()
  }
  handleSubmit = () => {
    console.log(this.title.current.value)
    console.log(this.refs.myInput.value)
  }
  render() {
    return (
      <div>
        <input type="text" ref={this.title}/>
        <input type="text" ref='myInput'/>
        <button onClick={this.handleSubmit}>提交</button>
      </div>
    );
  }
}

ReactDOM.render(
  <Form />,
  document.getElementById('root')
);
Publicado 139 artículos originales · elogiado 51 · 30,000+ vistas

Supongo que te gusta

Origin blog.csdn.net/Charissa2017/article/details/105642021
Recomendado
Clasificación