个人技术分享

官方文档

1,什么是 jsx

  • Facebook 起草的 js 扩展语法。
  • 本质上是 js 对象,会被 babel 编译,最终转换为 React.createElement() 语法。
  • 每个 jsx 表达式,有且仅有一个根节点。(因为函数只能有一个返回值
  • jsx 语法中,html标签必须闭合。

2,空标签

这个空标签被称作 Fragment。React Fragment 允许你将子元素分组,而不会在 HTML 结构中添加额外节点。

import { Fragment } from 'react';

function Post() {
  return (
    <Fragment>
      <PostTitle />
      <PostBody />
    </Fragment>
  );
}
// 或
function Post() {
  return (
    <>
      <PostTitle />
      <PostBody />
    </>
  );
}

通常只需要<> </>,除非需要将 key 传递给 Fragment。

3,通过大括号使用 js

因为 jsx 最终会被 babel 编译为 React.createElement() 语法。该语法中,除了第1,2个参数外,剩下的参数都会作为元素的子节点,所以在 jsx 中通过 {} 使用的 js 有一些限制:

1,不能是普通对象,但可以是 React 元素对象。

// 都是 React 元素对象,写法不同。
const obj = <span key={index}>一个span元素</span>;
const div = React.createElement("div", {}, `${a} * ${b} = ${a*b}`)

2,nullundefinedfalse 不会输出。
3,可以是数组,React 会遍历数组元素作为子节点。所以数组元素同样有上面规则和限制。

import React from "react";
import ReactDOM from "react-dom";

const span = <span>这是span元素</span>;
const arr = [2, null, false, undefined, 3, span];

const div = <div>{arr}</div>;
ReactDOM.render(div, document.getElementById("root"));

在这里插入图片描述

4,防止注入攻击

普通字符串中的html标签,react 会自动编码,采用 innerText 插入。edit HTML 查看初始 html 代码。

const content = "<h1>h1元素</h1><p>p元素</p>";
const div = <div>{content}</div>;

在这里插入图片描述

如果作为普通 HTML 插入,需要使用 dangerouslySetInnerHTML,只能对可信内容使用 HTML 插值,绝不要将用户提供的内容作为插值。

const content = "<h1>h1元素</h1><p>p元素</p>";
const div = <div dangerouslySetInnerHTML={{ __html: content }}></div>;

在这里插入图片描述

5,元素的不可变性

React 元素对象的所有属性,都不允许被修改。通过 Object.freeze() 实现。

React 元素对象:通过 React.createElement() 创建或在 jsx 中创建的:

在这里插入图片描述

此时不允许 div.props.xxxx 来修改对象属性。

如果确实需要更改元素对象的属性,需要重新创建JSX元素对象。

重新创建的是 js 对象,重新渲染也只是对比修改虚拟DOM,并不会太影响效率。

let num = 0

setInterval(() => {
  num++
  // 每次都新创建
  const div = <div title="22ss">{num}</div>
  ReactDOM.render(div, document.getElementById('root'))
}, 1000)

以上。