资讯专栏INFORMATION COLUMN

React专题:JSX

YorkChen / 2914人阅读

摘要:与之相对,语句的主要作用是逻辑和动作,没有返回值。函数行不行呢不行,因为它没有返回值。也就是说,等有返回值的遍历函数都是可以的。

本文是『horseshoe·React专题』系列文章之一,后续会有更多专题推出
来我的 GitHub repo 阅读完整的专题文章
来我的 个人博客 获得无与伦比的阅读体验

话说PHP是世界上最好的语言(笑)。

因为它的入门门槛极低。

";
foreach ($fruits as $fruit) {
    $str += "
  • " . $fruit . "
  • "; } $str += ""; ?>

    很多年前,这种字符串拼接开发网页的方式非常流行。

    但是这种写法有两个问题:

    容易造成XSS注入,有极大的安全风险。

    拼接的写法很繁琐。

    于是facebook的工程师开始动歪脑筋了。

    XHP

    他们的解决方案也很新颖,就是在代码里直接写标签,而不是将标签视为字符串。

    前面说到,字符串拼接很容易造成XSS注入。那么什么是XSS注入呢?

    比如恶意用户输入这么一段内容:,就可能被程序识别为一段脚本,他可以在脚本里面干任何事情。

    于是人们想到的办法是对所有输入转义,转义的作用就是让所有标签无法被识别为标签,而只是标签写法的字符串。用户的输入就会原原本本的展示在页面上。

    但是输入转义也有问题,就是容易把字符串拼接的标签也给转义了。大家应该看过页面上大段大段的标签写法的文本吧。

    我们来看看XHP的写法。

    
            

    {$post}

    Hey there.

    Like
    ;

    诶,是不是有点眼熟?

    XHP把标签与字符串区别开来了,变成脚本语法的一部分。

    这正好解决了前面提到的两个问题:

    标签就是标签,字符串就是字符串,再也别想浑水摸鱼。

    像写脚本一样写标签,是不是爽多了?

    JSX

    其实facebook一直在前端组件化方面做各种尝试,但都不是特别成功。

    直到2013年,工程师Jordan Walke提出一个大胆的想法:把XHP的写法迁移到JavaScript中来。即便有XHP的案例在前,大家还是觉得这个想法很疯狂。

    不过,facebook极为优秀的工程师文化最终促成了这种尝试。这一尝试不得了,开了天眼。

    自此之后就开启了React的开挂之路。

    const element = 

    Hello React!

    ;

    这不就是facebook一直在苦苦求索的前端组件化方案吗?

    刀耕火种时期的前端,入口是HTML,脚本和样式被引入到HTML页面上。这是一种分离化的思想,以语言为最小颗粒。

    然而经过大量痛苦的实践,人们发现以内容为最小颗粒才是正解。以组件为单位,页面结构、样式和功能都被集成在组件内部,对开发者来说组件就是一个黑匣子,只能通过暴露出来的接口使用组件。这是一种封装的思想,目的当然是为了复用。

    当然,目前React还无法实现真正意义上的CSS封装,不过以当下前端的关注度,CSS被彻底招安也指日可待。

    语法

    标签的写法和HTML一样,只不过融入到了JavaScript中。

    组件,其实就是自定义标签,首字母必须大写,为了与原生标签区别开来。

    如果标签或组件没有包含内容,可以采用自闭合标签写法。

    const element = ;

    JSX会自动忽略falsenullundefined

    标签的class属性和for属性要用className属性和htmlFor属性代替。

    组件返回多个标签或多个组件必须要用一个标签或组件包裹,也就是说只能有一个顶层元素。

    但是,React16以上的版本支持用空标签包裹或者直接返回数组。这样的好处就是不必添加很多无用的标签使页面变得更加臃肿。

    import React, { Fragment } from "react";
    
    const App = () => {
        return (
            
                
    React
    Vue
    Angular
    ); } export default App;
    import React from "react";
    
    const App = () => {
        return (
            <>
                
    React
    Vue
    Angular
    ); } export default App;
    import React from "react";
    
    const App = () => {
        return [
            
    React
    ,
    Vue
    ,
    Angular
    , ]; } export default App;
    表达式

    标签里肯定要写一些变量,要不然页面就是死的。

    怎么写变量呢?用花括号包围。

    const name = "React";
    const element = 

    Hello {name}!

    ;

    如果我想插入一个对象字面量怎么办?

    很简单,再包裹一层花括号。

    const obj = { name: "React" };
    const element = 

    Hello {name}!

    ;

    实际上花括号语法支持所有的表达式。

    那么问题来了,什么是表达式?

    简单来讲,表达式的主要作用是计算和声明,总是有返回值。与之相对,语句的主要作用是逻辑和动作,没有返回值。

    以下表达式JSX都支持。

    const a = ;
    
    const b = ;
    
    const c = 
    {popular ? "react" : "vue"}
    ; const d =
    {popular && "react"}
    ; const e =
    {renderSomething()}
    ;

    像赋值语句、判断语句和循环语句JSX都不支持。

    那开发者要渲染一个列表怎么办?

    for循环语句肯定是不行的,好在我们有map函数。因为从上例我们知道,JSX是支持函数执行表达式的。

    forEach函数行不行呢?不行,因为它没有返回值。也就是说,filter、find、reduce等有返回值的遍历函数都是可以的。

    import React, { Component } from "react";
    
    const list = ["react", "vue", "angular"];
    
    class App extends Component {
        render() {
            return (
                
    {list.map(value =>
    {value}
    )}
    ); } } export default App;
    编译

    不知道你们有没有这样的疑问:

    为什么返回多个标签或组件必须要用一个标签或组件包裹?

    为什么在根本没有使用React这个变量的情况下还要import React

    这里就要讲到JSX的编译。

    因为JSX不是正确的JavaScript语法,它要经过编译才能被浏览器识别。

    目前JSX的编译工作是由babel来完成的。

    我们来看看编译都做了哪些工作。

    下面的例子,后者是前者编译后的结果。

    const app = (
        
    );
    const app = React.createElement(
        "div",
        { className: "form" },
        React.createElement("input", { type: "text" }),
        React.createElement(
            "button",
            null,
            "click",
        ),
    );

    可以看到,标签最后变成了一个函数执行表达式,第一个参数是标签名,第二个参数是属性集合,之后的参数都是子标签。

    看到这里,相信也不用我解释了,前面提出的两个问题恍然大悟。

    整个UI实际上是通过层层嵌套的React.createElement方法返回的,所以我们要在文件开头import React,否则编译后就会发现createElement没有定义。

    React.createElement执行的结果是一个对象,对象的属性描述了标签或组件的性状,对象再嵌套子对象。如果顶层返回多个标签,就无法表达为一个对象了。

    由于React16引入了Fiber机制,使得返回多标签成为可能(并不清楚原因)。

    同时也回答了为什么标签的class属性和for属性要用className属性和htmlFor属性代替。在标签里属性怎么写都无所谓,但是classfor是JavaScript中的关键字,所以要换一种写法。

    React里面传递props有一种写法,如果传递的是一个对象,可以用扩展运算符很方便的传递。

    下面的例子,value先是被扩展运算符将属性分解,然后又被一个对象包裹。这里只是做了一个浅拷贝,并没有其他的含义。所以最终传递给组件的仍然是一个对象。

    所以疑问就来了,通常给组件传递属性都是键值对的形式,直接传递一个对象也可以吗?

    其实所有的属性最后都会放到一个对象里面,所以两种写法殊途同归。React只不过给了一种快捷方式。

    了解编译的过程,很多写法都很好理解了。

    const value = { a: 1, b: 2 };
    const element = ;
    const value = { a: 1, b: 2 };
    const element = ;
    React专题一览
    

    什么是UI
    JSX
    可变状态
    不可变属性
    生命周期
    组件
    事件
    操作DOM
    抽象UI

    文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

    转载请注明本文地址:https://www.ucloud.cn/yun/108351.html

    相关文章

    • React专题:什么是UI

      摘要:现代前端框架的使命就是开发者管理状态,框架根据状态自动生成。专题一览什么是可变状态不可变属性生命周期组件事件操作抽象 本文是『horseshoe·React专题』系列文章之一,后续会有更多专题推出来我的 GitHub repo 阅读完整的专题文章来我的 个人博客 获得无与伦比的阅读体验 什么是UI? 如果你指的是布局和色彩,那更偏向于设计师的工作。 在现代web领域,大家已经有一个共识...

      silvertheo 评论0 收藏0
    • React专题:可变状态

      摘要:的参数既可以是一个对象,也可以是一个回调函数。回调函数提供了两个参数,第一个参数就是计算过的对象,即便这时还没有渲染,得到的依然是符合直觉的计算过的值。专题一览什么是可变状态不可变属性生命周期组件事件操作抽象 本文是『horseshoe·React专题』系列文章之一,后续会有更多专题推出来我的 GitHub repo 阅读完整的专题文章来我的 个人博客 获得无与伦比的阅读体验 Reac...

      hosition 评论0 收藏0
    • React专题react,redux以及react-redux常见一些面试题

      摘要:我们可以为元素添加属性然后在回调函数中接受该元素在树中的句柄,该值会作为回调函数的第一个参数返回。使用最常见的用法就是传入一个对象。单向数据流,比较有序,有便于管理,它随着视图库的开发而被概念化。 面试中问框架,经常会问到一些原理性的东西,明明一直在用,也知道怎么用, 但面试时却答不上来,也是挺尴尬的,就干脆把react相关的问题查了下资料,再按自己的理解整理了下这些答案。 reac...

      darcrand 评论0 收藏0
    • 实例讲解react+react-router+redux

      摘要:而函数式编程就不一样了,这是模仿我们人类的思维方式发明出来的。数据流在中,数据的流动是单向的,即从父节点传递到子节点。数据流严格的单向数据流是架构的设计核心。 前言 总括: 本文采用react+redux+react-router+less+es6+webpack,以实现一个简易备忘录(todolist)为例尽可能全面的讲述使用react全家桶实现一个完整应用的过程。 代码地址:Re...

      RiverLi 评论0 收藏0
    • React 328道最全面试题(持续更新)

      摘要:希望大家在这浮夸的前端圈里,保持冷静,坚持每天花分钟来学习与思考。 今天的React题没有太多的故事…… 半个月前出了248个Vue的知识点,受到很多朋友的关注,都强烈要求再出多些React相前的面试题,受到大家的邀请,我又找了20多个React的使用者,他们给出了328道React的面试题,由我整理好发给大家,同时发布在了前端面试每日3+1的React专题,希望对大家有所帮助,同时大...

      kumfo 评论0 收藏0

    发表评论

    0条评论

    最新活动
    阅读需要支付1元查看
    <