React 中JSX语法 详解(如有纰漏和问题及时指出)

JSX

什么是JSX?

下面的链接放的是React官网中关于JSX语法介绍的知识

React官网关于JSX的描述

但是我们都知道官方文档一般不说人话, 说通俗一点就是让你在JS中书写html, 同时可以跟vue一样可以在其中使用表达式, 甚至可以插入JS, 下面给大家总结了几点JSX语法的特点

  • FaceBook起草的JS扩展语法
  • 本质上是一个JS对象,会被babel编译(如果还不知道babel是什么的话可以百度babel然后进官方文档查看, 大致上来说就是一个语法降级工具)
  • 每个JSX表达式, 有且仅有一个根节点
    因为JSX表达式最终会被编译成React.createElement, 例如
const h1 = (
    <h1>helloWorld<span>span元素</span></h1>
)

//上面这块会被编译成下面的内容
React.createElement('h1', {}, 'helloWorld', React.createElement('span', {}, 'span元素'));

//如果有两个根节点的话, babel将会不知道怎么编译, 没法用React.createElement来表示
const h1 = (
    <h1>helloWorld</h1>
    <span>span元素</span>
)

如果我们希望映射到真实的dom结构中是有两个根节点的话, 那么我们可能需要用到React.Fragment

const h1 = (
   <React.Fragment>
        <h1>helloWorld</h1>
        <span>span元素</span>
   </React.Fragment>
)
// 最后React.Fragment不会被映射进dom结构/ 类似于Vue的template

上面的React.Fragment其实还有一个语法糖, 写法如下

const h1 = (
   <>
    <h1>helloWorld</h1>
    <span>span元素</span>
   </>
)

// 实现的效果会跟React.Fragment一样
  • 每个JSX元素必须被闭合(遵循XML规范)

在JSX中嵌入表达式

  • 将表达式作为内容的一部分
const a = 10,
      b = 20;
const h1 = (
    <h1>{ a } * { b } = { a * b } </h1>
)

ReactDOM.render(h1, document.getElementById('root'));

// 那么页面会很标准的给我们渲染一个h1标签, 同时它的内容是 10 * 20 = 200

// 实际上上方的大括号被babel识别后, babel会给我们编译成如下

React.createElement('h1', null, `${a} * ${b} = ${a * b}`);

注意: null和undefined和false不会被显示

let a;
const h1 = (<h1>
                { null || a || false }  (/*这里的a和null和false都是不会被显示的*/)
            </h1>)

ReactDOM.render(h1, document.getElementById('root'));

不能放置普通对象, 我们常用来放置React元素对象

let infoArr = [
    {name: 'fuhong'},
    {name: 'fengzipeng'},
    {name: '灰克特'}
]

// map方法如果还不了解的话可能需要回去看一些JS基础, key值的话以后会讲授原理
const lists = infoArr.map((item, index) => <li key={index}>姓名: { item.name }</li>)

ReactDOM.render(lists, document.getElementById('root')); 
// 如上会给我们渲染一个li列表出来, 并且每个li中都是name 加上对应的item的name
  • 将表达式作为元素属性
const src = 'https://dss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1321783629,1938099303&fm=26&gp=0.jpg'; // 我们定义了一张图片链接

const class = 'demo'; // 定义了一个类名

const div = (
    <div>
        <img src = {src} alt = '德国牧羊犬'> 
        (/*当我们书写了src = {src}的时候 上方定义的src就会被解析到img元素中*/)
        <p className = {class}
           style = {{width: '200px', height: '300px', backgroundColor: 'red'}></p>
    </div>
)
  • 属性使用小驼峰命名法
  • 防止注入攻击

注入攻击的话大家如果不了解的话可以自行百度, React在防止XSS攻击也做得很好, 所以也给我们带来了不便, 如果我们真实的想将字符串作为innerHTML来解析的话, 我们需要如下操作

const content = '<h1>hello its me</h1>';
const div = (
    (/*当设置了dangerouslySetInnerHTML并按照如下书写以后, content将不会以innerText解析*/)
    <div dangerouslySetInnerHTML = {{ __html: content }}>
    </div>
)

元素的不可变性

  • 虽然JSX元素是一个对象, 但是该对象中的所有属性不可更改
let name = 'tom'
const h1 = (<h1>
                hello, { name } 
            </h1>)
// 如果我们要访问h1这个React对象中的文本name属性, 在目前我们只能用h1.props.children来找到他
// 小伙伴们可以自行打印查看
h1.props.children[1] = 'tommy';
ReactDOM.render(h1, document.getElementById('root'));

当我们进行更改以后, 页面一定会报错, 如下

在这里插入图片描述

它告诉我们不能去给只读属性分配值, 所以JSX中的所有属性都是不可更改的

  • 如果确实需要更改元素的属性, 那么我们需要重新创建JSX元素
let name = 'tom'
const h1 = (<h1>
                hello, { name } 
            </h1>)

// 第一次渲染
ReactDOM.render(h1, document.getElementById('root'));

// 我们要修改name的值以后再重新渲染一次
name = 'adam'; 
ReactDOM.render(h1, document.getElementById('root'));

因为React的虚拟dom所以如上操作不会每一次都增删DOM对象, 大家也不用担心造成性能的消耗, 至于虚拟DOM, 下回见

React的JSX语法到此结束, 如果有纰漏和问题欢迎补充, Thanks for Reading

发布了33 篇原创文章 · 获赞 11 · 访问量 2262

猜你喜欢

转载自blog.csdn.net/weixin_44238796/article/details/103434706
今日推荐