ReactJS读书笔记一:深入理解JSX

这个系列是读《React 引领未来的用户界面开发框架》的笔记。

JSX语法是react的一大亮点。
之前很不喜欢在js中写模板,因为js字符串换行很麻烦,所以大家都习惯把模板用script标签写在html中。后来发现这样其实挺坑的,特别是当你的网站是前后端分离的时候,如果改一下模板还要找后端的开发,非常浪费时间。
JSX的出现比较完美解决了JS中写模板的问题。简单的说就是JS 和 HTML和混合着写在一起。

一,JSX基本原理


首先我们看一个官方最简单的例子

  1. React.render(
  2. <h1color="red">Hello,world!</h1>,
  3. document.getElementById('example')
  4. );



然后他编译出来实际上是这样:

[javascript] copy
    React.render(React.createElement("h1",{color:"red"},"Hello,world!"),document.getElementById('example'));



其中最关键的部分就是 html 代码被转换成了 React.createElement。
这就是JSX的基本原理,他会自动识别html代码,并且全部转换成 React.createElement,于是编译出来的就是原生的JS代码。
如果你不嫌麻烦,完全可以自己写 React.createElement 来创建模板,这样就不需要JSX了。

JSX区分html代码的方式就是: 前括号之内并且首字母小写的就是html代码。如果首字母大写则就是react组件,后面会说到react组件。
JSX会有详细的语法检查,如果你的标签未闭合会直接报错。而不像浏览器中可能会自动修复或者直接乱掉。

因为JSX是兼容JS语法的,所以在html中如果有JS关键字就不要写,比如 class 要用 className 来代替。for 要用 htmlFor 来代替

二,HTML模板中使用JS


在HTML模板中使用JS非常方便,只需要用大括号把JS代码括起来即可。

编译出来就变成了这样:


要注意的是,大括号实际就是一个变量输出表达式,JSX最终就是直接把花括号中的内容作为React.createElement 的第三个参数直接传入了(没有任何修改直接传入),所以其中只能放一行表达式,并且任何不能直接作为第三个参数的写法都是错的,
那么你这样写就是错的:
copy
vara=1;
  • names.map( })
  • }
  • </div>,108); list-style-type:decimal-leading-zero; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> );


  • 因为很明显其中花括号内的内容直接放在第三个参数上,语法不对。

    这么写也是错的:
    因为 React.createElement(“div”,null,var a = 1;) 是语法错误。
    那么你也可以理解为什么大括号中的js表达式不能有分号结尾了吧。
    需要注意的是,如果你在属性中输出JS变量,是不能加引号的,不然会被当做字符串而不被解析。
    应该是这样:
    <atitle={title}>链接</a>

    三 组件嵌套

    JSX支持以XML的语法来嵌套组件:

      <Nav>Profile>click</>


    实际上生成了:
    copy
    React.createElement(Nav,
  • React.createElement(Profile,
  • 你也可以通过 JS 语法来写子节点:
  • copy
    >{login?>:Login>login>}

    四,延展属性 spread attributes

    后面会讲到如何创建React组件:
    copy
    varHelloMessage=React.createClass({
  • render:function(){
  • returnh1>Hello{this.props.name}>;
  • });
  • HelloMessagename="John"/>,108); list-style-type:decimal-leading-zero; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> document.getElementById('example')
  • 其中 props 可以认为是一个配置接口,在使用HelloMessage 组件的时候,传入的任何html属性都会保存在this.props 中
  • 这个属性不一定是字符串哦,可以是任何JS变量,比如:
    copy
    varHelloMessage=React.createClass({
  • render:function(){
  • return<h1>Hello{this.props.name()}</h1>;
  • varsayName=function(){
  • return"Lucy";
  • <HelloMessagename={sayName}/>,34)">那么请注意,这个 this.props 应该当做只读变量,不允许对他有任何修改,比如你不能 this.props.name =‘Lily’。这样是不符合规范的。因为他会导致组件和模板不一致。
  • 另外,有些时候你会需要直接把一个普通JS对象作为props 传递给 React组件,比如你从数据库中取到了一个人物信息,那么你可以用 延展属性操作符 来做:
    copy
    this.props.name}</h1>;
  • varLucy={
  • name:"Lucy",108); list-style-type:decimal-leading-zero; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> gender:"female"
  • <HelloMessage{...Lucy}/>,34)">
  • 注意其中的{…Lucy} 被编译成了:



    原理是不是很简单,就是一个类似 $.extend 的操作而已。

    五 一些需要注意的地方

    有几个在写JSX的时候需要注意的点

    1. 不要在HTML模板中写JS关键字,所以 class 应该用 className,for 应该用 htmlFor
    2. 所有的DOM标准属性都是驼峰命名,比如 onClick,但是 data-x 和 aria-x 还是用短横线分隔。
    3. style 属性接收的是一个key-value 的JS对象,而不是字符串。
    4. 所有的事件都是和W3C规范一致的!因为React内部对事件做了封装。
    5. 表单输入属性,例如valuechecked,以及textarea这里有更多相关信息
    参考:
    1. http://reactjs.cn/react/docs/jsx-in-depth.html
    2. http://www.jb51.cc/article/p-rkowmlmt-bnx.html

    版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

    相关推荐


    react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如果组件之中有复用的代码,需要重新创建一个父类,父类中存储公共代码,返回子类,同时把公用属性...
    我们上一节了解了组件的更新机制,但是只是停留在表层上,例如我们的 setState 函数式同步执行的,我们的事件处理直接绑定在了 dom 元素上,这些都跟 re...
    我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom 转为真实 dom 进行挂载。其实函数是组件和类组件也是在这个基础上包裹了一层,一个是调...
    react 本身提供了克隆组件的方法,但是平时开发中可能很少使用,可能是不了解。我公司的项目就没有使用,但是在很多三方库中都有使用。本小节我们来学习下如果使用该...
    mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接触 react 就一直使用 mobx 库,上手简单不复杂。
    我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc 端可以使用分页进行渲染数限制,在移动端可以使用下拉加载更多。但是对于大量的列表渲染,特别像有实时数据...
    本小节开始前,我们先答复下一个同学的问题。上一小节发布后,有小伙伴后台来信问到:‘小编你只讲了类组件中怎么使用 ref,那在函数式组件中怎么使用呢?’。确实我们...
    上一小节我们了解了固定高度的滚动列表实现,因为是固定高度所以容器总高度和每个元素的 size、offset 很容易得到,这种场景也适合我们常见的大部分场景,例如...
    上一小节我们处理了 setState 的批量更新机制,但是我们有两个遗漏点,一个是源码中的 setState 可以传入函数,同时 setState 可以传入第二...
    我们知道 react 进行页面渲染或者刷新的时候,会从根节点到子节点全部执行一遍,即使子组件中没有状态的改变,也会执行。这就造成了性能不必要的浪费。之前我们了解...
    在平时工作中的某些场景下,你可能想在整个组件树中传递数据,但却不想手动地通过 props 属性在每一层传递属性,contextAPI 应用而生。
    楼主最近入职新单位了,恰好新单位使用的技术栈是 react,因为之前一直进行的是 vue2/vue3 和小程序开发,对于这些技术栈实现机制也有一些了解,最少面试...
    我们上一节了了解了函数式组件和类组件的处理方式,本质就是处理基于 babel 处理后的 type 类型,最后还是要处理虚拟 dom。本小节我们学习下组件的更新机...
    前面几节我们学习了解了 react 的渲染机制和生命周期,本节我们正式进入基本面试必考的核心地带 -- diff 算法,了解如何优化和复用 dom 操作的,还有...
    我们在之前已经学习过 react 生命周期,但是在 16 版本中 will 类的生命周期进行了废除,虽然依然可以用,但是需要加上 UNSAFE 开头,表示是不安...
    上一小节我们学习了 react 中类组件的优化方式,对于 hooks 为主流的函数式编程,react 也提供了优化方式 memo 方法,本小节我们来了解下它的用...
    开源不易,感谢你的支持,❤ star me if you like concent ^_^
    hel-micro,模块联邦sdk化,免构建、热更新、工具链无关的微模块方案 ,欢迎关注与了解
    本文主题围绕concent的setup和react的五把钩子来展开,既然提到了setup就离不开composition api这个关键词,准确的说setup是由...
    ReactsetState的执行是异步还是同步官方文档是这么说的setState()doesnotalwaysimmediatelyupdatethecomponent.Itmaybatchordefertheupdateuntillater.Thismakesreadingthis.staterightaftercallingsetState()apotentialpitfall.Instead,usecom