• react入门基础准备


    React基础入门准备

    网页的局部刷新:ajax发请求,用户感知不到;js收到响应数据后,根据不同的结果来操作dom完成对页面的修改

    在React中,我们操作的是React元素,并不是原生真实的dom元素

    我们去修改dom, api复杂、考虑浏览器兼容性、性能不高,使用起来不方便;我们的框架可以帮助我们操作dom,我们不用直接操作dom,vue和react都有虚拟dom和diff算法,帮我们尽量减少真实dom的修改

    三个基础api

    基本使用:创建一个div并展示到页面

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <script
          crossorigin
          src="https://unpkg.com/react@18.0.0/umd/react.production.min.js"
        ></script>
        <script
          crossorigin
          src="https://unpkg.com/react-dom@18.0.0/umd/react-dom.production.min.js"
        ></script>
      </head>
      <body>
        <div id="root"></div>
        <script>
          // 原生js创建一个div元素展示到页面
          //   const div = document.createElement("div");
          //   div.innerText = "原生dom生成的div";
          //   document.getElementById("root").appendChild(div);
    
          // 1 创建一个react元素,它不是dom元素
          const div = React.createElement("div", {}, "这是react创建的div");
           // 2 获取根元素对应的react元素(盒子),接收一个dom元素
          const root = ReactDOM.createRoot(document.getElementById("root"));
           // 3 将div渲染到根元素中
          root.render(div);
        </script>
      </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    一、React.createElement()

    const reactDom=createElement('div',{},'')
    
    • 1

    作用:创建一个react元素

    参数

    1》元素的名称,必须小写

    2》标签中的属性

    ​ class属性需要使用className来设置,因为class是一个关键字

    ​ 在设置事件时,属性名需要改为驼峰命名法,为了区分原生

    3》子元素(元素内容)

    注意点:React元素最终会通过虚拟dom转换为真实的dom元素

    ​ React元素一定那创建就无法修改 ,只能替换

    ​ 修改React元素后,必须重新进行渲染

        <script>
          function changeBtnContent(content) {
            const button = React.createElement(
              "button",
              {
                type: "button",
                id: "btn",
              },
              content
            );
            const div = React.createElement(
              "div",
              { id: "div", className: "box" },
              "div盒子的内容",
              button
            );
            const root = ReactDOM.createRoot(document.querySelector("#root"));
            root.render(div);
          }
          changeBtnContent("点我");
          setTimeout(() => {
            const btn = document.querySelector("#btn");
            btn.addEventListener("click", () => {
              changeBtnContent("没问题,~");
            });
          }, 1000);
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    二、ReactDOM.createRoot(dom)

    获取根元素,根元素就是react元素要插入的位置

    const root=ReactDOM.createRoot(document.querySelector("#root"))
    
    • 1

    三、root.render(reactDom)

    用来将react元素渲染到根元素中

    根元素中所有的内容都会被删除,被react元素所替换,不会修改容器,只会修改容器的子节点

    重复调用render时,会比较两次的虚拟dom,确保只修改发生变化的元素,真实dom修改最少化

    JSX

    JSX是js的语法扩展,是得我们可以以类似html的形式去使用js;

    它是reac声明式编程的体现,是结果导向的编程 ;

    JSX是React.createElement()的语法糖 ,JSX最终都会转换为调用React.createElement()创建元素的代码

    使用JSX必须引入babel来进行编译;

      <body>
        <div id="root"></div>
        <script
          crossorigin
          src="https://unpkg.com/react@18.0.0/umd/react.production.min.js"
        ></script>
        <script
          crossorigin
          src="https://unpkg.com/react-dom@18.0.0/umd/react-dom.production.min.js"
        ></script>
        <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
        <script type="text/babel">
          const div = (
            <div>
              div的文字<button>按钮</button>
            </div>
          );
          const root = ReactDOM.createRoot(document.getElementById("root"));
          root.render(div);
        </script>
      </body>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    JSX注意事项:

    1》JSX不是字符串,不需要加引号

    2》JSX中所有的html标签应该小写,React组件应该大写开头

    3》JSX中有且只有一个根标签

    4》JSX的标签必须正确结束,html5中单标签可以省略/ ;但是JSX中不行

    5》在JSX中可以使用大括号{}来其纳入表达式(表达式就是有值的语句

    6》如果表达式是null,boolean,undefined,将不会显示

    7》在JSX中,属性可以直接赋值在标签中;但是class需要使用className, style={{backgroundColor:“red”}}

        <script type="text/babel">
          const uname = "--拥抱变成了煎熬";
          const div = (
            <div
              className="flower"
              style={{ backgroundColor: "skyblue", border: "2px solid red" }}
            >
              花田里犯了错
              {uname}
              {null}
              {undefined}
            </div>
          );
          const root = ReactDOM.createRoot(document.getElementById("root"));
          root.render(div);
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    8》列表渲染

    在JSX中,{}只能用来放js表达式,而不能放(if、for等语句); 但是js语句中可以操作JSX

    在JSX中,如果直接放入一个数组,他会自动的遍历

        <script type="text/babel">
          let arr = ["first", "second", "third"];
          const ul = <ul>{arr}</ul>;
          const root = ReactDOM.createRoot(document.querySelector("#root"));
          root.render(ul);
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    数组生成列表

        <script type="text/babel">
          let arr = ["first", "second", "third"];
          const jsxArr = [];
          //   for (let i = 0; i < arr.length; i++) {
          //     jsxArr.push(<li>{arr[i]}</li>);
          //   }
          //   const ul = <ul>{jsxArr}</ul>;
           // es6中map直接操作数组的每一项
          arr = arr.map((item) => <li>{item}</li>);
          const ul = <ul>{arr}</ul>;
           // 由于有返回值,所以也可以这样写;只是可读性差点,复杂的就还是分开
           //   const ul = (
           //     <ul>
           //       {arr.map((item) => (
           //         <li>{item}</li>
           //       ))}
           //     </ul>
           //   );
          const root = ReactDOM.createRoot(document.querySelector("#root"));
          root.render(ul);
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    虚拟dom与diff算法的简单理解

    React通过虚拟DOM,将React元素和原生dom进行映射,虽然操作的是React元素,但是这些操作最终都会在真实dom中体现出来

    虚拟dom的好处:

    1》降低API复杂度;

    2》解决兼容性问题;

    3》减少不必要的dom操作,提示性能

    每次调用root.render(),页面聚会重新渲染;React会同故宫diff算法,将新的元素和旧的元素进行比较;只会对发生变化的元素进行修改

        <button class="btn">修改列表内容</button>
        <div id="root"></div>
        <script type="text/babel">
          function showDom(arr) {
            const ul = (
              <ul>
                {arr.map((item) => (
                  <li>{item}</li>
                ))}
              </ul>
            );
            const root = ReactDOM.createRoot(document.querySelector("#root"));
            root.render(ul);
          }
          showDom(["a", "b", "c"]);
          const btn = document.querySelector(".btn");
          btn.onclick = () => {
            showDom(["a", "b", "c", "d"]);
          };
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在我点击按钮的时候,在列表中增加了一个li,其他的元素并没有变化

    它首先比较的式父元素,比较完父元素再比较子元素,子元素的类型和内容有没有变化,从第一个子元素开始比较,按顺序比较,这是它默认的比较方式

    但是有一个问题,比如我们点击传入的数组式[“d”,“a”, “b”, “c”],那么新的第1、2、3、4个li的内容分别和原来的第1、2、3比较,都不一样,导致所有的li都需要更新,显然是不好的

    所以React提供了一个key值,数组中的每一个元素都设置一个唯一的key,那么比较的时候按照key来比较,而不是默认的子元素顺序比较;

              <ul>
                {arr.map((item) => (
                  <li key={item}>{item}</li>
                ))}
              </ul>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这样原来三个li,key值分别为a、b、c; 点击按钮新生成的key分别为a、b、c、d;a、b、c比较时内容和类型都没有变,所以不需要更新,只需要新增d

    注意:

    我们一般采用id作为key值,因为他们唯一,而且是不会变化的;这样就可以保证我们比较的时候,即使顺序变了,也能保证没变的不更新

    尽量不要使用index作为key,因为它会随着顺序的改变而变化,所以使用索引index作为key和跟没有key一样;只是控制台不会警告;只是如果元素的顺序不会发生变化时,使用index作为key也没问题

  • 相关阅读:
    26、类型别名
    如何使用Iptables在Linux网关上转发端口
    [AI]大模型稳定角色扮演形成“自我认知”
    【《C Primer Plus》读书笔记】第11章:字符串和字符串函数
    LeetCode中等题之求解方程
    【GlobalMapper精品教程】005:影像拼接与裁剪案例教程
    计算机毕设 flink大数据淘宝用户行为数据实时分析与可视化
    【2012NOIP普及组】T3. 摆花 试题解析
    CentOS7.4下gSOAP-2.8编译
    excel数据丢失怎么办?表格文件恢复的3个方法
  • 原文地址:https://blog.csdn.net/weixin_50576800/article/details/125610554