1. Understand JSX syntax

Here is a piece of JSX syntax

<script type="text/babel">
  const element = <h2>Hello World</h2>
 ReactDOM.render(element, document.getElementById("app"));
</script>
Copy the code

What is JSX?

  • JSX is a JavaScript syntax eXtension, also known in many places as JavaScript XML because it looks like an XML syntax;
  • It’s used to describe our UI, and it’s perfectly compatible with JavaScript (so it’s flexible);
  • It is different from the module syntax in Vue. You do not need to learn the instructions in module syntax (such as V-for, V-if, V-else, V-bind).

Why React chose JSX?

  • React argues that rendering logic is intrinsically coupled to other UI logic

    • For example, the UI needs to bind events (buttons, A native, etc.);
    • For example, the UI needs to display data state, and when some state changes, the UI needs to be changed.
  • They are inseparable, so React doesn’t separate tags into different files. Instead, it groups them together. This is called components.

JSX writing specification:

  • The top level of JSX can only have one root element, so we often wrap a div primitive around it (or use the Fragment we’ll learn about later);
  • Labels in JSX can be single or double labels. (note: if it is a single tag, it must end with />;)
  • We usually wrap parentheses () around JSX to make it easy to read, and JSX can be written on a newline; Here’s an example:
 return(< div > < h2 > movie list 1 < / h2 > < ul > {liArray} < / ul > < h2 > movie list 2 < / h2 > < ul > {this. State. Movies. The map ((item) = > {return <li>{item}</li>
                })
              }
            </ul>
          </div>
        )
Copy the code

1.2 JSX embedding expression

If the content in JSX is dynamic, we can get it from an expression:

  • Writing rule: {expression}
  • Braces can contain variables, strings, arrays, function calls, and other js expressions. Here’s an example:

Comments in 1.2.1 JSX

JSX is a syntax embedded in JavaScript, so when writing comments, you need to use JSX syntax:

<h2>Hello World</h2> </div>Copy the code

1.2.2JSX embedded variables

  • If the variable is Number, String, or Array, it can be displayed directly
  • When the variable is null, undefined, or Boolean, the content is empty.
    • If you want to display null, undefined, or Boolean, convert it to a string.
    • There are many ways to convert, such as toString method, concatenation with empty String, String(variable), etc.
  • The object type cannot be a not valid as a React child or an error will be reported
class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      name: "why",
      age: 18,
      hobbies: ["Basketball"."Sing dance"."rap"].test1: null,
      test2: undefined,
      flag: false,

      friend: {
        name: "kobe",
        age: 40
      }
    }
  }

  render() {
    return(< div > {/ * I am a comment * /} < h2 > Hello World < / h2 > < / div > < div > {/ * 1. Can directly display * /} < h2 > {this. State. The name} < / h2 > < h2 > {this. State. The age} < / h2 > < h2 > {this. State. Hobbies} < / h2 > {/ * 2. Do not display * /} < h2 > {this. State. Test1} < / h2 > < h2 > {this. State. Test1 +""}</h2>
        <h2>{this.state.test2}</h2>
        <h2>{this.state.test2 + ""}</h2>
        <h2>{this.state.flag}</h2>
        <h2>{this.state.flag + ""}</h2> 123{this.state.friend}</h2> </div>)}} reactdom.render (<App/>, document.getelementbyid ("app"));
Copy the code

Why null, undefined, and Boolean are displayed as empty contents in JSX?

  1. Do not display a content when the result is false;
  2. Display a content when the result is true;

At this point, we can write the following code:

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      flag: false}}render() {
    return( <div> {this.state.flag ? < h2 > < / h2 > I am headings: null} {this. State. Flag && < h2 > I am a title < / h2 >}}} < / div >)Copy the code

1.2.3JSX embedded expression

In JSX, it can also be an expression.

  1. Operational expression
  2. Ternary operator
  3. Execute a function
class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      firstName: "kobe",
      lastName: "bryant",
      age: 20
    }
  }

  render() {
    return(<div> {/* operational expression */} <h2>{this.state.firstName +""+ this. State. The lastName} < / h2 > {/ * * the ternary operator /} < h2 > {this. State. The age > = 18?"Adult": "Minor"}</h2> {/* Execute a function */} <h2>{this.sayHello("kobe")}</h2>
      </div>
    )
  }

  sayHello(name) {
    return "Hello "+ name; }}Copy the code

1.2.4 JSX binding Properties

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

  1. For example, all elements have a title attribute
  2. For example, an img element would have a SRC attribute
  3. For example, the a element would have an href attribute
  4. For example, the element may need to be bound to a class. (Note: the class binding is special, because class is a keyword in JS, so JSX does not allow you to write the class directly.)
  5. For example, inline style is used natively. (style is an object type followed by the style’s property name and value. Note that the property name is converted to the hump identifier instead of the hyphen -;)

The following is how to write the various property bindings

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      title: "Hello?",
      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",
      active: false}}render() {
    return (
      <div>
        <h2 title={this.state.title}>Hello World</h2>
        <img src={this.state.imgUrl} alt=""/>
        <a href={this.state.link} target="_blank"</a> <div className={"message " + (this.state.active ? "active": ""</div> <div className={["message", (this.state.active ? "active": "")].join(""</div> <div style={{fontSize:"30px", color: "red", backgroundColor: "blue"I am text </div> </div>)}}Copy the code

1.3 JSX Event Listening

1.3.1 Differences from native binding

Native DOM native has a listener event, and the general operation is:

  1. Get DOM native, add listening events;
  2. In HTML native, bind onclick directly;
<button onclick="btnClick()"</button> //btnClick() </button> <script>function btnClick() {
  console.log("The button was clicked.");
}
</script>
Copy the code

How does React operate de?

There are two main differences in React event listening

  1. React events are named camelCase instead of pure lowercase.
  2. 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}>)btnClick() {
    console.log("React button clicked.")}}Copy the code

1.3.2 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: this.state.message
    • 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, Li Yinhe."}}render() {
    return(<div> <button onClick={this.btnclick}>)btnClick() { console.log(this); console.log(this.state.message); }}Copy the code

Why undefined?

  • The reason is that we don’t call the btnClick function actively, and React calls the btnClick function internally when the button changes.
  • 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

  • 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

But if I have two functions that use the btnClick binding we find that bind(this) has to be written twice; :

<button onClick={this.btnclick.bind (this)}> React </button> <button OnClick ={this.btnclick.bind (this)}> React </button>Copy the code

We can fix this by binding this directly to this.btnclick in the constructor (note our constructor: this.btnclick = this.btnclick.bind (this);). :

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      message: "Hello, Li Yinhe."
    }

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

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

Scheme 2: Use ES6 Class Fields syntax

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 = {
      message: "Hello, Li Yinhe."}}render() {
    return<div> <button onClick={this.btnclick}> React </button> </div> ) } btnClick = () => { console.log(this); console.log(this.state.message); }}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, so we just call this.btnclick ();
  • In this.btnclick (), this is used to specify that the binding will be implicit, and eventually this is correct;
class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      message: "Hello, Li Yinhe."}}render() {
    return(<div> <button onClick={() => this.btnclick ()}> React </button> React </button> </div>btnClick() { console.log(this); console.log(this.state.message); }}Copy the code

1.3.3 Event Parameter Transfer

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}> </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: ["Clothes"."Shoes"."Pants"]}}render() {
    return (
      <div>
        <a href="http://www.baidu.com"OnClick ={this.aclick}> </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

The author made a summary by learning codeWhy’s React course