React(一)react概述、组件、事件

简介: React(一)react概述、组件、事件

一、React概述

       React 是一个声明式,高效且灵活的用于构建用户界面的 JavaScript 库。使用 React 可以将一些简短、独立的代码片段组合成复杂的 UI 界面,这些代码片段被称作“组件”。


       详细教程可参见官网:

React 官方中文文档 – 用于构建用户界面的 JavaScript 库

https://react.docschina.org/


React框架的书写方式分为两种,一种是脚本方式(JavaScript标签引入,练习使用);一种是react脚手架方式(常用)。


1.脚本方式创建react初始模板

       为了能够正常使用react框架进行编程,我们创建好自己的项目之后,需要在页面中引入两个CDN链接:react库 和 react-dom库;


<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>

       对于这两个远程地址也可直接在官网下载到本地之后直接用<script src=""></script>引入项目中;如下:

image.png



<script src="./react.development.js"></script>
<script src="./react-dom.development.js"></script>

       除此之外还应注意,React 认为渲染逻辑本质上与其他 UI 逻辑内在耦合,比如,在 UI 中需要绑定处理事件、在某些时刻状态发生变化时需要通知到 UI,以及需要在 UI 中展示准备好的数据。所以在React中使用的是JSX语法,但是浏览器不识别JSX,我们就需要引入babel(Babel 中文网 · Babel - 下一代 JavaScript 语法的编译器)来解析翻译,而且需要在script写上对应属性,格式如下:


//引入Babel
<script src="./babel.min.js"></script>
<script type="text/babel">
    //内容
</script>

       引入所需要的链接之后,就需要创建挂载点(其实就是一个带有id名的div)了,专门用于插入后续生成的内容,如下:


<div id="root"></div>

这样,一个完整的react初始模板就完成了,总结起来为三步:


(1)在页面中引入 react 库 和 react-dom 库;


(2)引入 Babel;


(3)创建挂载点。


完整代码如下:


<!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>react入门</title>
  </head>
  <body>
    <!-- 挂载点:后续生成的内容插入这里 -->
    <div id="root"></div>
    <!-- 引入react的js文件 -->
    <script src="./react.development.js"></script>
    <script src="./react-dom.development.js"></script>
    <!-- 浏览器不识别JSX,需要引入babel来解析翻译,而且需要在script写上对应属性 -->
    <script src="./babel.min.js"></script>
    <script type="text/babel">
    </script>
  </body>
</html>

2.react的封装

封装react共有三步:


(1)创建虚拟DOM对象;创建对象包含有3个参数,标签名、属性(对象格式)、标签内的内容;


(2)获取挂载点;


(3)渲染页面。


格式如下:

<body>
    <!-- 引入react的js文件 -->
    <script src="./react.development.js"></script>
    <script src="./react-dom.development.js"></script>
    <script src="./babel.min.js"></script>
    <!-- 挂载点:后续生成的内容插入这里 -->
    <div id="root"></div>
    <script type="text/babel">
      // 1.创建虚拟DOM对象
      const vNode = React.createElement(
        //参数表示:标签,属性(对象格式),内容
        "div",
        {
          id: "mydiv",
          className: "cls",
        },
        "hello react!"
      );
      // 2.获取挂载点
      const root = document.getElementById("root");
      // 3.页面渲染
      ReactDOM.render(vNode, root);
    </script>
  </body>
</html>

此封装过程也可用JSX语法来写:


<body>
    <!-- 引入react的js文件 -->
    <script src="./react.development.js"></script>
    <script src="./react-dom.development.js"></script>
    <!-- 挂载点:后续生成的内容插入这里 -->
    <div id="root"></div>
    <!-- 浏览器不识别JSX,需要引入babel来解析翻译,而且需要在script写上对应属性 -->
    <script src="./babel.min.js"></script>
    <script type="text/babel">
      // 1.创建标签对象
      // JSX语法:在JS代码中写XML(类HTML)
      const vNode = (
        <div id="mydiv" className="cls">
          hello react JSX!
        </div>
      );
      // 2.获取挂载点
      const root = document.getElementById("root");
      // 2.渲染页面
      ReactDOM.render(vNode, root);
    </script>
  </body>

       可以看出,JSX语法最大区别在于省去了创建虚拟DON对象的步骤,而是直接创建一个标签对象,在该标签对象中直接按照HTML格式书写代码即可,其余两步则不变。


二、组件

       组件,从概念上类似于 JavaScript 函数。它接受任意的入参(即 “props”),并返回用于描述页面展示内容的 React 元素。React 定义组件有两种方式:


       函数方式,rfc react function component;某些不能使用;


       类方式,rcc react class component;功能更为强大;


1.函数方式定义组件

<body>
    <!-- 挂载点:后续生成的内容插入这里 -->
    <div id="root"></div>
    <!-- 引入react的js文件 -->
    <script src="./react.development.js"></script>
    <script src="./react-dom.development.js"></script>
    <!-- 浏览器不识别JSX,需要引入babel来解析翻译,而且需要在script写上对应属性 -->
    <script src="./babel.min.js"></script>
    <script type="text/babel">
      // 利用函数的封装性和复用性实现组件的复用
      // 规范要求:函数名称大写驼峰命名
      function Hello() {
        return <h1>Hello 组件!</h1>;
      }
      let h = Hello();
      // -------------------------------------------------------------
      // JSX语法
      // 复用
      // JSX语法中调用函数需要写JS语法,JS语法在JSX中写时需要使用{}括起来
      // h = (
      //   <div>
      //     {Hello()}
      //     {Hello()}
      //     {Hello()}
      //   </div>
      // );
      // -------------------------------------------------------------
      // 语法糖写法:标签方式调用(推荐)
      h = <Hello />;
      // 语法糖复用
      h = (
        <div>
          <Hello />
          <Hello />
          <Hello />
        </div>
      );
      // -------------------------------------------------------------
      // 渲染
      ReactDOM.render(h, document.getElementById("root"));
    </script>
  </body>

2.函数组件传参

<body>
    <!-- 挂载点:后续生成的内容插入这里 -->
    <div id="root"></div>
    <!-- 引入react的js文件 -->
    <script src="./react.development.js"></script>
    <script src="./react-dom.development.js"></script>
    <!-- 浏览器不识别JSX,需要引入babel来解析翻译,而且需要在script写上对应属性 -->
    <script src="./babel.min.js"></script>
    <script type="text/babel">
      // 定义函数组件
      // JSX语法中执行JS代码要用{}包裹
      function HelloName(props) {
        //return <h1>Hello{props}</h1>;
        return <h1>Hello{props.name}</h1>;
      }
      // 调用组件
      //let h = HelloName("你好"); //传值
      let h = HelloName({ name: "good" }); //传对象
      // -----------------------------------------------------------------------
      // 语法糖写法(推荐)
      h = <HelloName name="语法糖调用" />;
      // 复用
      h = (
        <div>
          <HelloName name="语法糖调用" />
          <HelloName name="推荐使用语法糖" />
        </div>
      );
      // -----------------------------------------------------------------------
      // 渲染
      ReactDOM.render(h, document.getElementById("root"));
    </script>
  </body>

3.类方式定义组件

<body>
    <!-- 挂载点:后续生成的内容插入这里 -->
    <div id="root"></div>
    <!-- 引入react的js文件 -->
    <script src="./react.development.js"></script>
    <script src="./react-dom.development.js"></script>
    <!-- 浏览器不识别JSX,需要引入babel来解析翻译,而且需要在script写上对应属性 -->
    <script src="./babel.min.js"></script>
    <script type="text/babel">
      // 定义一个类组件
      class Hello extends React.Component {
        //定义类继承React父类
        // 类方法:类属性+类方法
        // 类方法
        // 默认语法糖标签调用会调用此方法(意思就是如果用语法糖写法只能用render,用其他则会报错,所以建议使用render方法)
        render() {
          return <h1>Hello 类组件!</h1>;
        }
      }
      // 实例化
      let h = new Hello().render();
      // 语法糖调用
      h = <Hello />;
      h = (
        <div>
          {new Hello().render()}
          {new Hello().render()}
          <Hello />
          <Hello />
        </div>
      );
      // 渲染
      ReactDOM.render(h, document.getElementById("root"));
    </script>
  </body>

4.类组件传参

<body>
    <!-- 挂载点:后续生成的内容插入这里 -->
    <div id="root"></div>
    <!-- 引入react的js文件 -->
    <script src="./react.development.js"></script>
    <script src="./react-dom.development.js"></script>
    <!-- 浏览器不识别JSX,需要引入babel来解析翻译,而且需要在script写上对应属性 -->
    <script src="./babel.min.js"></script>
    <script type="text/babel">
      // 定义类组件并接收参数
      class HelloName extends React.Component {
        render() {
          // this代表当前类内,可以通过它调用类成员
          return <h1>Hello {this.props.name}</h1>;
        }
      }
      // 实例化
      let h = new HelloName({ name: "类组件传参" }).render();
      // 语法糖传参
      h = <HelloName name="语法糖传参" />;
      // 复用
      h = (
        <div>
          {new HelloName({ name: "JS调用类组件1" }).render()}
          {new HelloName({ name: "JS调用类组件2" }).render()}
          <HelloName name="语法糖调用1" />
          <HelloName name="语法糖调用2" />
        </div>
      );
      // 渲染
      ReactDOM.render(h, document.getElementById("root"));
    </script>
  </body>

三、事件

       React 元素的事件处理和 DOM 元素的很相似,但是有一点语法上的不同:React 事件的命名采用小驼峰式(camelCase),而不是纯小写。使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串。


       事件绑定使用的是JS原生写法:

<body>
    <!-- 挂载点:后续生成的内容插入这里 -->
    <div id="root"></div>
    <!-- 引入react的js文件 -->
    <script src="./react.development.js"></script>
    <script src="./react-dom.development.js"></script>
    <!-- 浏览器不识别JSX,需要引入babel来解析翻译,而且需要在script写上对应属性 -->
    <script src="./babel.min.js"></script>
    <script type="text/babel">
      // 定义组件+事件处理方法
      class App extends React.Component {
        // 类成员方法
        show() {
          alert("点击成功!");
        }
        render() {
          return (
            <div>
              {/*this代表当前类的成员,此处show不能加括号,因为事件必须点击后执行,如果加了括号就直接执行了*/}
              <button onClick={this.show}>点击按钮</button>
            </div>
          );
        }
      }
      // 渲染
      ReactDOM.render(<App />, document.getElementById("root"));
    </script>
  </body>

事件中this的指向:严格模式下指向window,非严格模式下为undefined;


解决方式:


(1)定义普通函数,调用时 bind 替换 this 并不触发执行;


{this.add.bind(this)}

(2)也使用箭头函数来定义方法,这样正常进行调用;


//定义
add=()=>{}
//调用
{this.add}

(3)定义普通函数,调用时先调用箭头函数,再由箭头函数调用普通函数。


{()=>this.add}

如下:使用bind函数替换this指向、使用箭头函数触发


<body>
    <!-- 挂载点:后续生成的内容插入这里 -->
    <div id="root"></div>
    <!-- 引入react的js文件 -->
    <script src="./react.development.js"></script>
    <script src="./react-dom.development.js"></script>
    <!-- 浏览器不识别JSX,需要引入babel来解析翻译,而且需要在script写上对应属性 -->
    <script src="./babel.min.js"></script>
    <script type="text/babel">
      class App extends React.Component {
        // 类成员
        // 属性
        name = "Hello React!";
        // 方法
        show() {
          console.log("普通函数:" + this.name);
        }
        // 箭头函数方法
        show1 = () => {
          console.log("箭头函数:" + this.name);
        };
        render() {
          return (
            <div>
              {/*用bind绑定this,bind(this)将方法中的this替换为App*/}
              <button onClick={this.show.bind(this)}>普通函数触发</button>
              <br />
              <button onClick={this.show1}>箭头函数触发</button>
            </div>
          );
        }
      }
      // 渲染
      ReactDOM.render(<App />, document.getElementById("root"));
    </script>
  </body>


相关文章
|
4月前
|
资源调度 前端开发 JavaScript
React 的antd-mobile 组件库,嵌套路由
React 的antd-mobile 组件库,嵌套路由
42 0
|
20小时前
|
存储 前端开发 JavaScript
【亮剑】如何处理 React 中的 onScroll 事件?
【4月更文挑战第30天】在React中,处理`onScroll`事件可实现复杂功能如无限滚动和视差效果。类组件和函数组件都能使用`onScroll`,通过`componentDidMount`和`componentWillUnmount`或`useEffect`添加和移除事件监听器。性能优化需注意节流、防抖、虚拟滚动、避免同步计算和及时移除监听器。实战案例展示了如何用Intersection Observer和`onScroll`实现无限滚动列表,当最后一项进入视口时加载更多内容。合理利用滚动事件能提升用户体验,同时要注意性能优化。
|
4天前
|
JavaScript 前端开发 开发者
深入比较Input、Change和Blur事件:Vue与React中的行为差异解析
深入比较Input、Change和Blur事件:Vue与React中的行为差异解析
|
29天前
|
JSON API 网络架构
FastAPI+React全栈开发13 FastAPI概述
FastAPI是一个高性能的Python Web框架,以其快速编码和代码清洁性著称,减少了开发者错误。它基于Starlette(一个ASGI框架)和Pydantic(用于数据验证)。Starlette提供了WebSocket支持、中间件等功能,而Pydantic利用Python类型提示在运行时进行数据验证。类型提示允许在编译时检查变量类型,提高开发效率。FastAPI通过Pydantic创建数据模型,确保数据结构的正确性。FastAPI还支持异步I/O,利用Python 3.6+的async/await关键词和ASGI,提高性能。此外,
37 0
|
29天前
|
前端开发 JavaScript 开发者
如何在React中监听键盘事件
如何在React中监听键盘事件
35 0
|
3月前
|
存储 前端开发 中间件
React组件间的通信
React组件间的通信
17 1
|
3月前
|
前端开发 JavaScript Java
react事件机制
react事件机制
39 0
|
3月前
|
前端开发 应用服务中间件 数据库
react服务端组件
react服务端组件
21 0
|
3月前
|
前端开发 JavaScript
快速上手React:从概述到组件与事件处理
快速上手React:从概述到组件与事件处理
|
3月前
|
开发框架 前端开发 JavaScript
探索前端开发中的跨平台框架React Native
本文将介绍前端开发中一种备受关注的跨平台框架React Native,通过比较原生应用与React Native的优缺点,探讨其在实际项目中的应用以及未来发展趋势。