Knowledge points that need to be learned

1. Listening events

2. This point

3. Arrow function

4.e.preventDefault() cancels the default behavior of a target element

JSX binding properties

Many times, the HTML native of the description will have attributes that we want to be dynamic as well:

  • For example, all elements have a title attribute
  • For example, an img element would have a SRC attribute
  • For example, the a element would have an href attribute
  • For example, elements may need to be bound to a class
    • Note: Binding class is special because class is a keyword in JS, so JSX does not allow you to write classes directly
    • Write: use className instead
  • Such as using inline style style natively
    • Style is followed by an object type that contains the style’s property name and property value.
    • Note: The property name is converted to the hump identifier, not the hyphen -;

Let’s demonstrate property binding

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      title"You better study hard.".imgUrl"https://upload.jianshu.io/users/upload_avatars/1102036/c3628b478f06.jpeg?imageMogr2/auto-orient/strip|imageView2/1/w/24 0/h/240".link"https://www.baidu.com".activefalse}}render() {
    const {title, imgUrl, link} = this.state
    return (
      <div>{/*1. Bind common attributes */}<h2 title={title}>Hello World</h2>
        <img src={imgUrl} alt=""/>
        <a href={link} target="_blank">The baidu</a>
        <label htmlFor=""></label>Class * /} {/ * 2. The binding<div className={"message"+ (this.state.active ? "active":"")} >Hello.</div>
        <div className={["message", (this.state.active ? "active": "")].join(" ")} >Hello.</div>{/ * 3. The binding style * /}<div style={{fontSize: "30px", color: "red", backgroundColor: "blue}} ">I am a text</div>
      </div>)}}Copy the code

JSX event listening

Different from native binding

What if the native DOM native has a listening event?

  • Method 1: obtain DOM native, add listening events;

  • Method 2: In HTML native, directly bind onclick;

  • BtnClick () is written this way because the onclick binding is followed by JavaScript code;

<button onclick="btnClick()"</button><script>
  function btnClick({
  console.log("The button was clicked.");
}
</script>
Copy the code

How does React work?

Let’s implement event listening in React. There are two main differences

  • React events are named camelCase instead of pure lowercase.
  • We need to pass in an event handler with {}, which will be executed when the event occurs;
class App extends React.Component {
  render() {
    return (
      <div>
        <button onClick={this.btnClick}>Tap me React</button>
      </div>)}btnClick() {
    console.log("React button clicked.")}}Copy the code

This binding problem

After the event is executed, we may need to get the relevant attributes in the object of the current class:

  • For example, here we print:this.state.message
    • But there is an error:Cannot read property 'state' of undefined
    • The reason is that this is undefined here
  • If we just print this here, we’ll see that it’s undefined as well
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      message"Hello, Lu Yinhe."}}render() {
    return (
      <div>
        <button onClick={this.btnClick}>Tap me React</button>
      </div>)}btnClick() {
    console.log(this);
    console.log(this.state.message); }}Copy the code

Why undefined?

  • The reason is thatbtnClickThe function is not called by us actively, and React is called internally when the button changesbtnClickFunctions;
  • And when it calls internally, it doesn’t know how to bind the right this;

How to solve this problem?

Option 1: Bind to btnClick to show bind this

When passing in a function, we can actively bind this:

  • Here we are actively binding this in btnClick via bind (show binding)
  • Then when we call the btnClick function inside React, we’ll have a this, which we’ll bind to;
<button onClick={this.btnClick.bind(this}> React </button>Copy the code

However, if I have two functions that both need the btnClick binding:

  • We found thatbind(this)You have to write it twice;
<button onClick={this.btnClick.bind(this}> React </button><button onClick={this.btnClick.bind(this)}>Tap me too (React)</button>
Copy the code

We can fix this by binding this directly to this.btnClick in the constructor:

  • Pay attention to seeconstructorIn our operation:this.btnClick = this.btnClick.bind(this);
class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      message"Hello, Lu Yinhe."
    }

    this.btnClick = this.btnClick.bind(this);
  }

  render() {
    return (
      <div>
        <button onClick={this.btnClick}>Tap me React</button>
        <button onClick={this.btnClick}>Tap me too (React)</button>
      </div>)}btnClick() {
    console.log(this);
    console.log(this.state.message); }}Copy the code

Option 2: Use arrow functions that never bind this

You’ll notice that I’ve changed the definition of btnClick into an assignment statement:

  • This is the way in ES6 that attributes a class, called the Class Fields syntax;
  • Because we’re using the arrow function here, this in the current function will look up in the previous scope;
  • This in the previous scope is the current object;
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      counter= 100}}render() {
    return (
      <div>
        <button onClick={this.increment}>+ 1</button>
      </div>)} {/*increment () { console.log(this.state.counter) }*/}
  
  increment = () = > {
    console.log(this.state.counter)
  }
}
Copy the code

Scenario 3: Passing in arrow functions for event listening (recommended)

Since onClick requires us to pass in a function, we can simply define an arrow function to pass in:

  • The body of the arrow function passed in is the code we need to execute, which we do directlythis.btnClick();
  • this.btnClick()This is used to specify that implicit binding will take place, and this is correct in the end;
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      message"Hello, Lu Yinhe."}}render() {
    return (
      <div>
        <button onClick={()= >This.btnclick ()}> React</button>
        <button onClick={()= >This.btnclick ()}> React</button>
      </div>)}btnClick() {
    console.log(this);
    console.log(this.state.message); }}Copy the code

Event Parameter passing

When executing an event function, it is possible that we need to get some parameter information: for example, the event object, other parameters

Case 1: Get the Event object

  • Many times we need to get the Event object to do something (such as prevent the default behavior)
  • If we don’t need this, we can just pass in the function to get the event object.
class App extends React.Component {
  constructor(props) {
  render() {
    return (
      <div>
        <a href="http://www.baidu.com" onClick={this.btnClick}>Point me</a>
      </div>)}btnClick(e) {
    e.preventDefault();
    console.log(e); }}Copy the code

Case two: Get more parameters

  • When we have more arguments, our best bet is to pass in an arrow function, an active event function, and pass in other arguments that are relevant;
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      names: ["css"."js"."react"]}}render() {
    return (
      <div>
        <a href="http://www.baidu.com" onClick={this.aClick}>Point me</a>

        {
          this.state.names.map((item, index) => {
            return (
              <a href="#" onClick={e= > this.aClick(e, item, index)}>{item}</a>)})}</div>)}aClick(e, item, index) {
    e.preventDefault();
    console.log(item, index);
    console.log(e); }}Copy the code