React的基本语法和原理

发布于:2025-08-01 ⋅ 阅读:(17) ⋅ 点赞:(0)

3. React条件渲染

    1. 某些情况下,姐妹的内容会根据不同的情况显示不同的内容,或者决定是否渲染某部分内容:
    • 在React中,所有的条件判断和普通的JavaScript代码一致;
    1. 常见的条件渲染的方式有哪些?
    • 方式一: 条件判断语句

      • 适合逻辑较多的情况
    • 方式二: 三元运算符

      • 适合逻辑比较简单
    • 方式三: 与运算符&&

      • 适合如果条件成立,渲染某一个组件;如果条件不成立,什么内容也不渲染
    • v-show的效果

      • 主要是控制display属性是否为none
    • 示例代码如下:

      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
      </head>
      <body>
        <div id="root"></div>
      
        <script src="../lib/react.js"></script>
        <script src="../lib/react-dom.js"></script>
        <script src="../lib/babel.js"></script>
      
        <script type="text/babel">
          // 1.定义App根组件
          class App extends React.Component {
            constructor () {
              super()
              this.state = {
                message: 'hello world',
                isReady: false,
                friend: undefined
              }
            }
      
            render () {
              const  { isReady, friend } = this.state
              // 1.条件判断方式一: 使用if进行条件判断
              let showElement = null
              if(isReady) {
                showElement = <h2>准备开始比赛吧</h2>
              } else {
                showElement = <h2>请提前做好准备!</h2>
              }
              return  (
                <div>
                  { /* 1. 方式一: 根据条件给变量赋值不同的内容 */ }
                  <div>{ showElement }</div>
                  { /* 2. 方式二: 三元运算符 */ }
                  <div>{ isReady ? <button>开始战斗!</button> : <h3> 赶紧准备 </h3> }</div>
                  { /* 3. 方式三: && 逻辑与运算符 */ } 
                  { /* 场景: 当某一个值, 有可能为undefined时,使用&&进行条件判断 */  }
                  {/* 转成Boolean值时不显示的 */}
                  <div>{ friend && <div>{ friend.name + ' ' + friend.desc }</div> }</div>
                </div>
              )
            }
          }
          // 2. 创建root并且渲染App组件
          const root = ReactDOM.createRoot(document.querySelector('#root'))
          root.render(<App/>)
        </script>
      </body>
      </html>
      
      

4. React列表渲染

    1. 真实开发中会从服务器请求大量的数据,数据会以列表的形式存储:
    • 比如歌曲、歌手、排行榜列表的数据;
    • 比如商品、购物车、评论列表的数据;
    • 比如好友消息、动态、联系人列表的数据;
    1. 在React中没有像Vue模板语法中的v-for指令,而是需要通过Javascript代码的方式组织数据,转成JSX;
    • 很多从Vue转到React的非常不习惯,认为Vue的方式更贱简洁明了;
    • 但是React中的JSX正式因为和Javascript无缝的衔接,让他可以更加的灵活;
    • React是真正可以提高我们编写代码能力的一种方式;
    1. 如何展示列表
    • 在React中,展示列表最多的方式就是使用数组的map方法
    1. 很多时候在展示一个数组中的数据之前,需要先对他进行一些处理;
    • 比如过滤掉一些内容:filter函数
    • 比如截取数组中的一部分内容: slice函数
    • 示例代码如下:
      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
          .item {
            border: 1px solid orange;
            margin: 10px;
            padding: 0 20px;
          }
      
        </style>
      </head>
      <body>
        <div id="root"></div>
      
        <script src="../lib/react.js"></script>
        <script src="../lib/react-dom.js"></script>
        <script src="../lib/babel.js"></script>
      
        <script type="text/babel">
          // 1.定义App根组件
          class App extends React.Component {
            constructor () {
              super()
              this.state = {
                students: [
                  { id: 111, name: 'why', score: 199 },
                  { id: 112, name: 'kobe', score: 98 },
                  { id: 113, name: 'james', score: 199  },
                  { id: 114, name: 'curry', score: 188 }
                ]
              }
            }
      
            render () {
              const  { students } = this.state
      
              // 分数大于100的学生进行展示
              const filterStudents = students.filter( item => item.score > 100)
      
              // 分数大于100,只展示两个人信息
              // slice(start, end): [start, end)
              const sliceStudents = students.slice(0,2)
              return  (
                <div>
                  <h2>学生列表数据</h2>
                  <div className="list">
                  {
                    students.filter(item => item.score> 100).slice(0, 2).map(item => {
                      return (
                        <div className="item">
                          <h2>学号:{item.id}</h2>  
                          <h3>姓名:{item.name}</h3>  
                          <h1>分数:{item.score}</h1>  
                        </div>  
                      )
                    })
                  }
                    
                  </div>
                </div>
              )
            }
          }
          // 2. 创建root并且渲染App组件
          const root = ReactDOM.createRoot(document.querySelector('#root'))
          root.render(<App/>)
        </script>
      </body>
      </html>
      
    1. 列表中的key
    • 在前面的代码中只要展示列表都会有报一个警告:
      • 警告:Warning: Each child in a list should have a unique “key” prop.
      • 翻译:在一个列表中每个子元素都应该有唯一的"key"属性
      • 作用:在某些情况下(例如:插入)提高diff算法的效率
      • 警告如图:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
      • 添加key属性后警告不提示:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
    • 这个警告是告诉需要再列表展示的jsx中添加一个key
      • key主要的作用是为了提高diff算法的效率
      • 具体内容后续再进行写笔记

5. JSX的本质

    1. 实际上,jsx仅仅只是React.createElement(component, props, …children)函数的语法糖;
    • 所有的jsx最终都会被转换成React.createElement的函数调用。
    1. createElement需要传递三个参数:
    • 参数一:type
      • 当前ReactElement的类型
      • 如果是标签元素,那么就使用字符串表示
      • 如果是组件元素,那么就直接使用组件的名称
    • 参数二:config
      • 所有jsx中的属性都在config中以对象的属性和值的形式存储
      • 比如传入className作为元素的class;
    • 参数三: children
      • 存放在标签中的内容,以children数组的方式进行存储;
      • 当然,如果是多个元素呢? React内部有对他们进行处理,处理的源码在下放
        外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
    1. babel官网查看
    • 默认jsx是通过babel帮我进行语法转换的,所以之前写的jsx代码都需要依赖babel。
    • 可以子啊babel的官网中快速查看转换的过程:https://babeljs.io/repl#?browsers=react
      外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
    1. 自己编写React.createElement代码:
    • 没有通过jsx来书写,姐妹依然是可以正常的渲染;
    • 另外,在这样的情况下,不需要babel相关的依赖
      • 所以,type="text/babel"可以删掉
      • 所以,可以删除掉了;
      • React.createElement代码如下:
          React.createElement(
            "div",
            null,
      
    /#PURE/ React.createElement(
    “div”,
    {
    className: “header”
    },
    “Header”
    ),
    /#PURE/ React.createElement(
    “div”,
    {
    className: “Content”
    },
    /#PURE/ React.createElement(“div”, null, “Banner”),
    /#PURE/ React.createElement(
    “ul”,
    null,
    /#PURE/ React.createElement(
    “li”,
    null,
    “\u5217\u8868\u6570\u636E1”
    ),
    /#PURE/ React.createElement(
    “li”,
    null,
    “\u5217\u8868\u6570\u636E2”
    ),
    /#PURE/ React.createElement(
    “li”,
    null,
    “\u5217\u8868\u6570\u636E3”
    ),
    /#PURE/ React.createElement(
    “li”,
    null,
    “\u5217\u8868\u6570\u636E4”
    ),
    /#PURE/ React.createElement(“li”, null, “\u5217\u8868\u6570\u636E5”)
    )
    ),
    /#PURE/ React.createElement(
    “div”,
    {
    className: “footer”
    },
    “Footer”
    )
    );
    
    
    

6. 虚拟DOM创建的过程

    1. 通过React.createElement做种创建出来一个ReactElement对象;
    • return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);
    1. 这个ReactElement对象是什么作用? React为什么要创建它
    • 原因是React利用ReactElement对象组成了一个Javascript的对象树
    • Javascript的对象树就是虚拟DOM(Virtual DOM)
    1. 如何查看ReactElement对象
    • 可以将之前的jsx返回结果进行打印;
    • 注意下面代码中jsx的打印;
      外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
      外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
      外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
    1. 而ReactElement最终形成的树结构就是Virtual DOM;
    1. jsx -> 虚拟DOM -> 真实DOM
    • 编写相应的jsx代码,jsx代码转换完之后会变成对应的React.createElement()这样的一个函数调用,当函数执行完之后,会形成ReactElement对象;
      并且这个对象也会有嵌套,有自己的children, 它也会形成一个嵌套,形成嵌套的话它就形成就是一个虚拟DOM,而虚拟DOM的话再经过渲染最后就变成真实的DOM;
    • jsx代码 -> ReactElement对象 -> 真实DOM
    • div -> React.createElement('div', null, {}) -> ReactElement对象 -> 虚拟DOM -> 真实DOM
    • jsx代码外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
    • ReactElement对象外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
    • 真实DOM外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
    • 类比Vue:是template解析 -> render函数 -> h函数 -> vnode -> 虚拟dom -> 真实dom
    • 类比Vue解析,Vue解析时没有React直观的,Vue结项相对来说麻烦一点,有各种指令
    1. 虚拟DOM的作用:
      1. 在更新数据时,没有必要重新把整个一段代码给重新渲染,只需要更新数据,然后重新渲染对应的数据即可
      • 例如:当依赖一个数据message, 当message数据改变时,会重新调用render函数,一旦调用render函数就会形成一个新的结构, 重新执行时会在次调用createElement,就会形成一个新的虚拟DOM结构,然后还有一个旧的虚拟DOM结构,会在新旧虚拟DOM之间做一个diff算法,比较新旧虚拟DOM之间的不同,如果只是数据发生改变时,只需要更新数据就可以了。
      • 总结:可以在更新的时候进行diff算法,然后决定更新那里(可以在js对象里面快速进行diff算法来决定哪些东西更新,那些东西不更新)
      1. 跨平台,可以做跨平台应用程序
      1. 虚拟DOM帮助我们从命令式编程转到了声明式编程的模式;
  • 声明式编程

      1. 虚拟DOM帮助我们从命令式编程转到了声明式编程的模式;
      1. React官方的说法:Virtual DOM 是一种编程理念
      • 在这个理念中,UI以一种理想化或者虚拟化的方式保存在内存中,并且它是一个相对简单的Javascript对象;
      • 可以通过root.render()让虚拟DOM和真实ODM同步起来,这个过程叫做协调(Reconciliation)
      • 协调:div -> ReactElement对象 -> 虚拟DOM -> 真实DOM
      1. 这种编程方式赋予React声明式的API:
      • 只需要告诉React希望让UI是什么状态;
      • React来确保DOM和这些状态是匹配的;
      • 不需要直接进行DOM操作,就可以从手动更改DOM、属性操作、事件处理中解放出来;

网站公告

今日签到

点亮在社区的每一天
去签到