5
头图

join us!

Mountain" , to provide front-end developers with technical information and a series of basic articles. For a better user experience, please move to our official website rookies (160d13d23cf918 https://xhs-rookies.com/ ) to learn and get the latest articles in time.

"Code tailor" , if you are interested in our article or want to make some suggestions, follow Mountain" public account, contact us, you can also watch it on WeChat Our article. Every suggestion or approval is a great encouragement to us!

Preface

This section we will teach you a funny tag syntax, he neither strings nor HTML , he was called JSX , is a JavaScript syntax extensions, we recommend React with the use JSX , JSX can be well described UI It should show its essential form of interaction.

This article will introduce you to the following:

  • Know the syntax of JSX
  • Embed expressions in JSX
  • Event monitoring
  • Conditional rendering
  • List rendering
  • JSX principle analysis
  • Case exercise

Know the syntax of JSX

What is JSX?

Let's first look at a piece of code:

const element = <h1>Hello, XHS-Rookies!</h1>

What is the label syntax for the assignment on the right side of the element

This interesting tag syntax is neither a string nor HTML .

It is called JSX and is a syntax extension of JavaScript We recommend React in conjunction with JSX . JSX can well describe how the UI should present its essential form of interaction. JSX may be reminiscent of a template language, but it has all the functions of JavaScript

Note: for JSX , although a JavaScript syntax extension, but you can find it can not be used directly in HTML , the need to use babel conversion, the conversion will automatically help I resolved to the style you want.

Why use JSX?

React believes that rendering logic is UI logic. For example, UI needs to bind processing events, needs to notify UI when the state changes at certain moments, and needs to display prepared data UI

React does not adopt the artificial separation method of separating the mark and logic into different files, but realizes separation of concerns by storing the two together in loosely coupled units called "components".

React not mandatory to use JSX , but most people find that JavaScript JSX and UI together in the 060d13d23cfcd5 code will help visually. It can also make React display more useful error and warning messages.

JSX writing specification:

  • JSX the top can have only one root element , so we will often wrapped in a layer div native;
  • In order to facilitate reading, we usually jsx , so that it is easy to read, and jsx can be written in a new line;
  • JSX can be single label or double label;
Note: is a single label, it must end />

Embedding expressions in JSX

If jsx is dynamic, we can get it by expression:

Writing rules: {expression}, inside the braces can be any js expressions such as variables, strings, arrays, function calls, etc.;

Comments in JSX

This is JavaScript , so when you write a comment, you need to write JSX

<div>
  {/* 我是一段注释 */}
  <h2>Hello World</h2>
</div>

JSX embedded variables

Case 1: When the variable is Number , String , Array , it can be displayed directly

Case 2: When the variable is of null , undefined , Boolean , the content is empty;

  • If you want to display null , undefined , Boolean , then you need to convert to a string; there are many ways to convert, such as toString method, and empty string splicing, String (variable), etc.;

case three: object type cannot be used as a child element ( not valid as a React child )

class App extends React.Component {
  render() {
    let data = {
      name: 'xhs-rookies',
      age: 18,
      skills: ['JavaScript', 'React', 'Webpack'],

      test1: null,
      test2: undefined,
      flag: false,

      friend: {
        name: 'xhs-zymxxxs',
        age: 29,
      },
    }
    return (
      <div>
        <div>
          {/* 我是一段注释 */}
          <h2>Hello React</h2>
        </div>

        <div>
          {/* 1.可以直接显示 */}
          <h2>{data.name}</h2>
          <h2>{data.age}</h2>
          <h2>{data.skills}</h2>

          {/* 2.不显示 */}
          <h2>{data.test1}</h2>
          <h2>{data.test1 + ''}</h2>
          <h2>{data.test2}</h2>
          <h2>{data.test2 + ''}</h2>
          <h2>{data.flag}</h2>
          <h2>{data.flag + ''}</h2>

          {/* 3.不显示 */}
          <h2>123{data.friend}</h2>
        </div>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('app'))

Why are null, undefined, and Boolean displayed as empty content in JSX? reason for 160d13d23cff7f is that a lot of judgments will be made during development;

  • When the judgment result is false, no content is displayed;
  • When the judgment result is true, display a content;

JSX embedded expression

In JSX syntax, you can put any valid JavaScript expression inside the curly braces. For example, 2 + 2, user.firstName or formatName(user) are all valid JavaScript expressions.

In the following example, we will call the result of the JavaScript function formatName(user) and embed the result in the <h1> element.

function formatName(user) {
  return user.firstName + ' ' + user.lastName
}

const user = {
  firstName: 'xhs',
  lastName: 'rookies',
}

const element = <h1>Hello, {formatName(user)}!</h1>

ReactDOM.render(element, document.getElementById('root'))

JSX binding properties

You can specify the attribute value as a string literal by using quotation marks:

const element = <div className="active"></div>

You can also use braces to insert a JavaScript expression in the attribute value:

const element = <img src={user.avatarUrl}></img>

When embedding the JavaScript expression in the attribute, do not put quotation marks around the curly braces. You should only use one of quotation marks (for string values) or curly braces (for expressions), and you cannot use both symbols for the same attribute.

Event monitoring

Difference from native binding

If the native DOM has a native listener event, how can we operate it?

  • Method 1: Obtain the DOM and add a monitoring event;
  • Method 2: In the HTML , directly bind onclick ;

Let’s rehearse method two here:

  • btnClick() The reason for this is written onclick behind is bound to keep JavaScript Code;
<button onclick="btnClick()">点我一下</button>
<script>
  function btnClick() {
    console.log('按钮发生了点击')
  }
</script>

How does it work in React

Let's implement React . There are two main differences here.

  • React event adopts small hump ( camelCase ) instead of pure lower case;
  • We need to pass in an event processing function via {}, this function will be executed when the event occurs;
class App extends React.Component {
  render() {
    return (
      <div>
        <button onClick={this.btnClick}>点我一下</button>
      </div>
    )
  }

  btnClick() {
    console.log('React按钮点击了一下')
  }
}

This binding of the event

You must be treated with caution JSX callback function this , in JavaScript in, class the default method does not bind this . If you forget to bind this.handleClick and it was introduced to onClick , when you call this function this value undefined .

class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this)
  }

  render() {
    // 此语法确保 `handleClick` 内的 `this` 已被绑定。
    return <button onClick={() => this.handleClick()}>Click me</button>
  }
}

If you want to know bind and arrow function used for this , you can choose to view the difference between bind and arrow function

Event parameter passing

When executing the event function, it is possible that we need to obtain some parameter information: such as event object, other parameters

Case 1: Obtain the event object

  • Many times we need to get the event object to do some things (such as preventing the default behavior)
  • If we don't use this , then we can get the event object by directly passing in the function;
class App extends React.Component {
  btnClick(e) {
    e.preventDefault()
    console.log(e)
  }
  render() {
    return (
      <div>
        <a href="https://xhs-rookies.com/" onClick={this.btnClick}>
          点我一下
        </a>
      </div>
    )
  }
}

Case 2: Get more parameters

  • When there are more parameters, our best way is to pass in an arrow function, an event function that is actively executed, and pass in other related parameters;
class App extends React.Component {
  render() {
    let data = {
      names: ['衣服', '鞋子', '裤子'],
    }
    return (
      <div>
        <a href="https://xhs-rookies.com/" onClick={this.aClick}>
          点我一下
        </a>

        {data.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)
  }
}

Conditional rendering

In some cases, the content of the interface will display different content according to different situations, or decide whether to render a certain part of the content:

In React , all condition judgments are consistent with the JavaScript

What are the common conditional rendering methods?

Conditional statement

One way is to pass conditional judgment when there is more logic:

class App extends React.Component {
  render() {
    let data = {
      isLogin: true,
    }
    let titleJsx = null
    if (data.isLogin) {
      titleJsx = <h2>欢迎回来~</h2>
    } else {
      titleJsx = <h2>请先登录~</h2>
    }

    return <div>{titleJsx}</div>
  }
}

Of course, we can also encapsulate it in a separate function:

class App extends React.Component {
  this.data = {
    isLogin: true
  }

  render() {
    return (
      <div>
        {this.getTitleJsx()}
      </div>
    )
  }

  getTitleJsx() {
    let titleJsx = null;
    if (this.data.isLogin) {
      titleJsx = <h2>欢迎回来~</h2>
    } else {
      titleJsx = <h2>请先登录~</h2>
    }
    return titleJsx;
  }
}

Ternary operator

Another way to implement conditional rendering is the ternary operator: condition ? true : false;

The ternary operator is suitable for code without much logic: it just returns different results directly according to different conditions

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      isLogin: true,
    }
  }

  render() {
    return (
      <div>
        <h2>{this.state.isLogin ? '欢迎回来~' : '请先登录~'}</h2>
        <button onClick={(e) => this.loginBtnClick()}>
          {this.state.isLogin ? '退出' : '登录'}
        </button>
      </div>
    )
  }

  loginBtnClick() {
    this.setState({
      isLogin: !this.state.isLogin,
    })
  }
}

AND operator &&

In some cases, we will encounter such scenarios:

  • If the condition is true, render a certain component;
  • If the conditions are not met, nothing will be rendered;

If we use the ternary operator, how do we do it?

{
  this.state.isLogin ? <h2>{this.state.username}</h2> : null
}

In fact, we can simplify the operation logical AND &&:

{
  this.state.isLogin && <h2>{this.state.username}</h2>
}

List rendering

List rendering

During development, we will request a large amount of data from the server, and the data will be stored in the form of an array.

We need to organize the data by way of JavaScript JSX .

Let's practice a case:

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

    this.state = {
      skills: ['HTML', 'CSS', 'JavaScript', 'React', 'Node'],
    }
  }

  render() {
    return (
      <div>
        <h2>前端技能</h2>
        <ul>
          {this.state.skills.map((item) => {
            return <li>{item}</li>
          })}
        </ul>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('app'))

Array processing

Many times we need to do some processing on the data in an array before displaying it:

  • For example, filter out some content: filter function
  • For example, intercept part of the contents of the array: slice function

For example, I currently have a series of numbers stored in an array: [10, 30, 120, 453, 55, 78, 111, 222]

Case requirement: Get all numbers greater than or equal to 50 from a given array, and display the first 3 numbers

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

    this.state = {
      numbers: [10, 30, 120, 453, 55, 78, 111, 222],
    }
  }

  render() {
    return (
      <div>
        <h2>数字列表</h2>
        <ul>
          {this.state.numbers
            .filter((item) => item >= 50)
            .slice(0, 3)
            .map((item) => {
              return <li>{item}</li>
            })}
        </ul>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('app'))

List key

We will find that in the previous code, as long as the list is displayed, a warning will be reported:

image.png list display warning

This warning tells us that we need to add a key jsx shown in the list.

As for why key needed, here is react component rendering. When the list is particularly long, or DOM node are sent to change, such as when adding an element at the end of the child element list, you just need to add Just put the content at the end, there is no problem.

But if you need to add new elements to the head of the list, the overhead will be very large. In order to solve this similar problem, React introduced. After the key is used for optimization, the conversion efficiency of the tree will be improved.

For details about the key content, please see:

List & Key – React (reactjs.org)

depth understanding of why the key is necessary

JSX principle analysis

JSX transformation essence

In fact, jsx is just syntactic sugar for the React.createElement(component, props, ...children) React.createElement will eventually be converted into function calls of 060d13d23d0b2a. If you want to learn more JSX implementation principles, please refer to depth JSX

Case exercise

List display

In real development, our data is usually obtained from the server. It is more common to obtain a list of data and save it to an array for display.

  • For example, there is a to-do list now, how can we display it through React?

We still do it through a component:

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

    this.state = {
      things: ['写文章', '开会', '上课', '读书'],
    }
  }

  render() {
    return (
      <div>
        <h2>代办事项列表</h2>
        <ul>
          {this.state.things.map((item, index) => {
            return <li>{index + 1 + '.' + item}</li>
          })}
        </ul>
      </div>
    )
  }
}

Like function case

There is no interaction in the case of the to-do list, let's implement a case of the like function:

class App extends React.PureComponent {
  constructor() {
    super()
    this.state = {
      isLike: false,
      likeNum: 233,
    }
  }

  likeOrUnlike() {
    if (this.state.isLike) {
      this.setState({
        isLike: false,
        likeNum: this.state.likeNum - 1,
      })
    } else {
      this.setState({
        isLike: true,
        likeNum: this.state.likeNum + 1,
      })
    }
  }

  render() {
    console.log('render')
    return (
      <div>
        <p>点赞人数:{this.state.likeNum}</p>
        <button onClick={(e) => this.likeOrUnlike()}>
          {this.state.isLike ? '取消点赞' : '点赞'}
        </button>
      </div>
    )
  }
}

小和山的菜鸟们
377 声望2.1k 粉丝

每日进步的菜鸟,分享前端学习手册,和有心学习前端技术的小伙伴们互相探讨,一同成长。