ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# JSX 前面一直提到 JSX 语法,那么JSX到底是什么? >[success] JSX是一种 JavaScript 的语法扩展,Javascript和XML结合的一种格式。React发明了JSX,利用HTML语法来创建虚拟DOM。当遇到<,JSX就当HTML解析,遇到{就当JavaScript解析。 ## 使用JSX应该注意的几点 第一, 在 JSX 中使用的“ 元素” 不局限于 HTML 中的 元素, 它可以是任何一个 React 组件,比如我们之前创建的 `Counter` 组件。 React 判断 一个元素是 HTML 元素还是 React 组件的原则就是看第一个字母是否大写, 如果在 JSX 中我们不用 `Counter` 而是用 `counter`, 那就得不到我们想要的结果。 第二, 在 JSX 中可以通过 `onClick` 这样的方式给一个元素添加一个事件处理函数, 当然, 在 HTML 中也可以用 onclick( 注意和 `onClick` 拼写有区别), 但在 HTML 中直接书写 onclick 一直就是为人诟病的写法, 网页应用开发界一直倡导的是用 jQuery 的方法添加事件处理函数, 直接写 onclick 会带来代码混乱的问题。 并不推荐在组件中直接使用 `onclick`,而是使用 `onClick`,主要是 `onclick` 有以下几个缺点: - onclick 添加的事件处理函数是在全局环境下执行的, 这污染了全局环境, 很容易产生意料不到的后果; - 给很多 DOM 元素添加 onclick 事件, 可能会影响网页的性能, 毕竟, 网页需要的事件处理函数越多, 性能就会越低; - 对于使用 onclick 的 DOM 元素, 如果要动态地从 DOM 树中删掉的话, 需要把对应的时间处理器注销, 假如忘了注销, 就可能造成 内存泄露, 这样的 bug 很难被发现。 然而,在 JSX 中并不存在上述缺点。 在 JSX 中,使用 `onClick` 并不是将事件直接挂在到对应的 DOM 中,而是使用事件委托,挂在到DOM树的最顶层中,这样,无论添加多少个 `onClick` ,在DOM树中都只有一个事件处理函数,再根据具体组件分派到不同的实现方法中。 (来自 [程墨. 深入浅出React和Redux (实战) (Kindle位置276). 机械工业出版社. Kindle 版本. ](),有改动) ## 使用JSX 可以将任意DOM元素赋值到一个常量: ```jsx const element = <h1>Hello, world!</h1>; ``` 也可以创建一个嵌套的DOM树 ```jsx const element = ( <div> <h1>Hello!</h1> <h2>Good to see you here.</h2> </div> ); ``` JSX 乍看起来可能比较像是模版语言,但事实上它完全是在 JavaScript 内部实现的。 也可以在JSX中使用任意js表达式,在JSX中使用js表达式需要使用一对大括号 `{}` ```js function formatName(user) { return user.firstName + ' ' + user.lastName; } const user = { firstName: 'Harper', lastName: 'Perez' }; const element = ( <h1> Hello, {formatName(user)}! </h1> ); ``` ### JSX 本身其实也是一种表达式 在编译之后,JSX 其实会被转化为普通的 JavaScript 对象。 这就意味着,其实可以在 if 或者 for 语句里使用 JSX,将它赋值给变量,当作参数传入,甚至作为函数返回值都可以: ```jsx function getGreeting(user) { if (user) { return <h1>Hello, {formatName(user)}!</h1>; } return <h1>Hello, Stranger.</h1>; } ``` ### JSX 属性 可以使用引号来定义以字符串为值的属性 ```jsx const element = <div tabIndex="0"></div>; ``` 可以使用大括号来定义以 JavaScript 表达式为值的属性 ```jsx const user = { avatarUrl: 'http://localhost/logo.png' } const element = <img src={user.avatarUrl} />; ``` 切记在使用大括号包裹的 JavaScript 表达式时就不要再到外面套引号了。JSX 会将引号当中的内容识别为字符串而不是表达式。 >[warning] 因为 JSX 的特性更接近 JavaScript 而不是 HTML , 所以 React DOM 使用 camelCase 小驼峰命名 来定义属性的名称,而不是使用 HTML 的属性名称。 >例如,class 变成了 className,而 tabindex 则对应着 tabIndex. ### JSX只是一个语法糖 本质上来讲,JSX 只是为 `React.createElement(component, props, ...children)` 方法提供的语法糖。 Babel 转译器会把 JSX 转换成 React.createElement() 的方法调用。 所以,以下两种写法完全相同: ```jsx const element = ( <h1 className="greeting"> Hello, world! </h1> ); ``` ```jsx const element = React.createElement( 'h1', {className: 'greeting'}, 'Hello, world!' ); ``` 编译后返回类似于以下结构的对象: ```jsx const element = { type: 'h1', props: { className: 'greeting', children: 'Hello, world' } }; ```