面试官:你是如何理解 JSX 的?

58 阅读3分钟

JSX 是一种 JavaScript 的语法扩展,因为看起来就是一段 XML 语法,所以也称之为 JavaScript XML。它的作用主要用于描述 UI 界面,可以和 JavaScript 很好的结合在一起使用,不同于 Vue 中的模版语法。

React 认为渲染逻辑本质上与其他 UI 逻辑存在内在的耦合 例如 UI 需要绑定事件、需要展示数据的状态,它们之间的关系是密不可分的,所以 React 将它们组合到了一起,而不是把它分离到不同的文件中。

JSX 规范

  1. JSX 结构中顶层只能有一个根元素,如 div 标签。

  2. JSX 结构通常会包裹一个(),将整个 JSX 当做一个整体,实现换行。

  3. JSX 可以是单标签,也可以双标签,但是单标签必须以 /> 结尾。

  4. JSX 的注释应该写在 {} 中。

class App extends React.Component {
  constructor() {
    super()
    this.state = {
      title: "React"
    }
  }

  render() {
    const { title } = this.state

    return (
      <div>
        { /* JSX的注释写法 */ }
        <h1>{title}</h1>
      </div>
    )
  }
}

JSX 子元素

  1. undefinedNullBoolean:不会被渲染,但是将其转为字符串就会显示。

  2. NumberStringArray:直接显示其值。

  3. Object 对象不能作为其子元素显示。

  4. {} 中可以书写 JavaScript 表达式和三目运算。

  5. {} 中可以调用函数获取结果。

JSX 属性绑定

class App extends React.Component {
  constructor() {
    super()
    this.state = {
      title: "React",
      className: "container",
      objStyle: {
        color: "black",
        textAlign: "center"
      }
    }
  }

  render() {
    const { title, className, objStyle } = this.state

    return (
      <div>
        { /* 1.基本属性绑定 */ }
        <h1 title={ title }>标题</h1>
        
        { /* 2.绑定 class 属性 */ }
        <div className={ className }>内容</div>

        { /* 3.绑定 style 属性 */ }
        <footer style={ objStyle }>尾部</footer>
      </div>
    )
  }
}

JSX 事件绑定

方式一:通过bind绑定

class App extends React.Component {
  constructor() {
    super()
    this.state = {
      title: "React"
    }
    this.btn1Click = this.btn1Click.bind(this)
  }

   btn1Click() {
     console.log("btn1Click", this);
     this.setState({ title: this.state.title + '学习笔记' })
  }

  render() {
    const { title } = this.state

    return (
      <div>
        { /* bind 绑定 */ }
        <h1>{ title }</h1>
        <button onClick={this.btn1Click}>修改标题</button>

      </div>
    )
  }
}

方式二:定义箭头函数方法

class App extends React.Component {
  constructor() {
    super()
    this.state = {
      title: "React"
    }
  }

  btn2Click = () => {
    console.log("btn2Click", this)
    this.setState({ title: this.state.title + '学习笔记' })
  }

  render() {
    const { title } = this.state

    return (
      <div>
        { /* 箭头函数方法绑定 */ }
        <h1>{ title }</h1>
        <button onClick={this.btn2Click}>修改标题</button>

      </div>
    )
  }
}

方式三:直接在 onClick 中使用箭头函数(推荐)

class App extends React.Component {
  constructor() {
    super()
    this.state = {
      title: "React"
    }
  }

  btn3Click() {
    console.log("btn3Click", this)
    this.setState({ title: this.state.title + '学习笔记' })
  }

  render() {
    const { title } = this.state

    return (
      <div>
        { /* 直接传入一个箭头函数 */ }
        <h1>{ title }</h1>
        <button onClick={() => this.btn3Click()}>修改标题</button>
      </div>
    )
  }
}

JSX 事件参数传递

直接在 onClick 中使用箭头函数传递参数:

class App extends React.Component {
  constructor() {
    super()
    this.state = {
      title: "React"
    }
  }

  btnClick(event, param) {
    console.log("btnClick", event, this)
    console.log("param:", param)
  }

  render() {
    const { title } = this.state

    return (
      <div>
        <h1>{ title }</h1>
        <button onClick={() => this.btnClick(event, "学习笔记")}>修改标题</button>
      </div>
    )
  }
}

JSX 本质

JSX 本质上只是 React.createElement(component, props, ...children) 函数的语法糖,最终都会被转换成 React.createElement 的函数调用。

第一个参数是 type 也就是当前 ReactElement 的类型,如果是标签元素,就直接写标签名,如div,如果是组件,直接使用组件名即可。

第二个参数是 config,所有 JSX 中的属性都在 config 中以对象的属性和值的形式存储,如传入 className 作为元素的 class。

第三个参数是 children,存放在标签中的具体内容。

举个例子,比如 <div class="title">点击</div> 这行代码就会被编译为:

React.createElement(div, {className: 'title'}, '点击')的函数调用。

总的来说,如果你的 JavaScript 功底非常好,基础非常扎实,那么我认为你在学习 React 的道路上会事半功倍,其本质就是在写 JavaScript 、在用 JavaScript。