I. Event handling
1. Event handling
The React element handles events similar to the DOM element, but with a few syntactic differences. Let’s look at a simple example
<! DOCTYPE html><html>
<head>
<title>Demo</title>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { counter: 0 };
// Bind the component instance to the event handler
// The purpose of binding component instances is to use this in event handlers
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
// The 'e' passed in here is a composite event
// Have the same interface as browser native events, including stopPropagation() and preventDefault()
this.setState((state) = > ({
counter: state.counter + 1
}));
}
render() {
return (
<div>
<p>{ this.state.counter }</p><br/>} {/* Pass in a function as an event handler instead of a string */}<button onClick={ this.handleClick} >Add 1</button>
</div>
);
}
}
ReactDOM.render(
<Counter />.document.getElementById('app'));</script>
</body>
</html>
Copy the code
2. This binding
In the above example, we bind this to the event handler function from constructor()
Note that in JavaScript, class methods are not bound to this by default, i.e
If we don’t bind this.handleClick and pass it to onClick, this will be undefined when we call this function
If you want to use this in event handlers, it is mandatory to bind this to event handlers in one of three ways:
(1) Use bind in the constructor
class PrintThis extends React.Component {
// Use 'bind' in the constructor
constructor(props) {
super(props)
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log(this)}render() {
return (
<button onClick={ this.handleClick} >Print This</button>); }}Copy the code
(2) Use the public Class Fields syntax in event handlers
class PrintThis extends React.Component {
constructor(props) {
super(props)
}
// Use 'public Class fields syntax' in event handlers
handleClick = () = > {
console.log(this)}render() {
return (
<button onClick={ this.handleClick} >Print This</button>); }}Copy the code
(3) Use arrow functions in callback functions
class PrintThis extends React.Component {
constructor(props) {
super(props)
}
handleClick = () = > {
console.log(this)}render() {
return (
<div>{/* Use 'arrow function' in callback function */}<button onClick={ (e) = > this.handleClick(e) }>Print This</button>
</div>); }}Copy the code
3. Pass parameters
Sometimes we also need to pass additional parameters to the event
class SayHello extends React.Component {
// Event handlers must receive arguments before synthesizing event 'e'
sayHelloTo(somebody, e) {
alert('Hello ' + somebody);
}
render() {
return (
<div>{/* You can use the arrow function */}<button onClick={ (e) = > this.sayHelloTo('Alice', e) }>Say Hello To Alice</button>Function.prototype.bind */}<button onClick={ this.sayHelloTo.bind(this, 'Bob') }>Say Hello To Bob</button>
</div>); }}Copy the code
Second, form elements
1. Controlled components
In HTML, form elements typically maintain their own state and are updated based on user input events
But in React, mutable state is usually stored in the component’s state property and can only be updated with the setState() method
A component is called a controlled component if we want its state to remain the only data source, while also controlling user input events
class InfoForm extends React.Component {
constructor(props) {
super(props)
this.state = { name: ' '.phone: ' ' } // Provide default values
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)}// Define a handler for the user event (state changed)
handleChange(event) {
// console.log(event.target)
const target = event.target
// If you need to process multiple input elements, you can perform different operations based on 'target.name'
if (target.name === 'userName') {
this.setState({ name: target.value })
} else { // target.name === 'userPhone'
this.setState({ phone: target.value })
}
}
handleSubmit(event) {
alert('Your name is' + this.state.name + '; ' + 'Your mobile phone is.' + this.state.phone)
event.preventDefault()
}
render() {
return (
The onSubmit attribute specifies the handler for the submit event
<form onSubmit={ this.handleSubmit} >{/* Type attribute specifies the type of input element */} {/* name attribute specifies the unique identifier of each input element */} {/* value attribute points to state data, Make state the only data source */} {/* onChange attribute specifies the handler for value changes */} Your name:<input type="text" name="userName" value={ this.state.name } onChange={ this.handleChange} / ><br /><br />Your Mobile phone:<input type="text" name="userPhone" value={ this.state.phone } onChange={ this.handleChange} / ><br /><br />
<input type="submit" value="Submit" />
</form>)}}Copy the code
2. Uncontrolled components
In addition to letting the React component manage form data through a controlled component, you can also use an uncontrolled component to let DOM nodes process form data
Instead of writing a handler for every status update, we can just use ref to get form data from the DOM node
class InfoForm extends React.Component {
constructor(props) {
super(props)
this.handleSubmit = this.handleSubmit.bind(this)
// create a ref with 'react.createref ()'
this.nameInput = React.createRef()
this.phoneInput = React.createRef()
}
handleSubmit(event) {
alert('Your name is' + this.nameInput.current.value + '; ' + 'Your mobile phone is.' + this.phoneInput.current.value)
event.preventDefault()
}
render() {
return (
The onSubmit attribute specifies the handler for the submit event
<form onSubmit={ this.handleSubmit} >The {/* type attribute specifies the type of the input element */} {/* ref attribute is used to get the value of the form element from the DOM node */} Your name:<input type="text" ref={ this.nameInput} / ><br /><br />Your Mobile phone:<input type="text" ref={ this.phoneInput} / ><br /><br />
<input type="submit" value="Submit" />
</form>)}}Copy the code