react实例与总结(一)

news2025/2/11 15:13:48

目录

一、简单认识

1.1、特点

1.2、JSX语法规则

1.3、函数组件和类式组件

1.4、类组件三大属性state、props、refs

1.4.1、state

1.4.2、props

1.4.3、refs

1.5、事件处理

1.6、收集表单数据—非受控组件和受控组件

1.7、高阶函数—函数柯里化

1.8、生命周期—新旧对比

1.8.1、旧16+

1.8.2、新17+

1.8.3、对比

1.9、DOM的Diffing算法

二、脚手架搭建

2.1、创建项目

  因为真实DOM频繁操作节点会导致页面重绘和重排,影响性能,所以会用虚拟DOM【应用于前端框架】进行跨平台开发

一、简单认识

英文:Getting Started – React

中文:快速入门 – React 中文文档

1.1、特点

(1)采用组件化模式、声明式编码,提高开发效率及组件复用率

(2)在React Native中使用它进行移动端开发

(3)使用虚拟DOM+Diffing算法,减少与真实DOM的交互

1.2、JSX语法规则

(1)、定义虚拟DOM时,不要写引号

(2)、标签中混入js表达式时要用{}

(3)、样式的类名指定不要用class,要用className

(4)、内联样式:要用style={{key:value}}形式

(5)、只有一个根标签,所有标签必须闭合

(6)、标签首字母

若小写字母开头,则将该标签转为html中同名元素;若html中没有该标签对应的同名元素,则报错

若大写字母开头,则react去找对应的组件,若找不到,则报错

在Microsoft Edge安装React Developer Tools扩展进行开发辅助,以下语法基于16+版本。

1.3、函数组件和类式组件

前者适用于简单组件(只能使用props属性,除非使用Hooks里的useRef 和 useState ),后者适用于复杂组件

    <div id="root"></div>
    <script type="text/babel">
      // 1.创建函数式组件
      function MyComponent() {
        return <h1>我是函数式组件</h1>;
      }
      // 2.渲染组件到页面
      ReactDOM.render(<MyComponent />, document.getElementById("root"));
    </script>
      // 1.创建类式组件
      class MyComponent extends React.Component {
        render() {
          //  render()中的this 指向当前组件实例
          return <h1>我是类式组件</h1>;
        }
      }
      // 2.渲染组件到页面
      ReactDOM.render(<MyComponent />, document.getElementById("root"));

1.4、类组件三大属性state、props、refs

注意:类组件里的render()会调用1+N次(只要state更新就变)

1.4.1、state

      class MyMood extends React.Component {
        state = {
          isGood: false,
          number: 0,
        };
        render() {
          const { isGood, number } = this.state;
          return (
            <div>
              <h1 onClick={this.changeMyMood}>
                今天心情很{isGood ? "好" : "糟糕"}
              </h1>
              <h1 onClick={() => this.setState({ number: 10 })}>
                打个{number}分
              </h1>
            </div>
          );
        }
        changeMyMood = () => {
          this.setState({
            isGood: !this.state.isGood,
          });
        };
      }
      ReactDOM.render(<MyMood />, document.getElementById("root"));

总结:

(1)、状态必须通过setState进行更新,且更新是一种合并,不是替换;

(2)、组件中render()方法中的this为组件实例对象,当this为undefined,如何解决?

a.通过函数对象的bind()强制绑定this;b.箭头函数

1.4.2、props

<div id="root1"></div>
<div id="root2"></div>
<div id="root3"></div>
    <script type="text/babel">
      class Person extends React.Component {
      // 使用 PropTypes 进行类型检查
      static propTypes = {
        name: PropTypes.string.isRequired,//必传项
        sex: PropTypes.string,
        age: PropTypes.number,
        onSuccess: PropTypes.func
      };
      // 设置默认属性
      static defaultProps = {
        age: 18,
        sex: "男"
      };
      render() {
          const { name, age, sex } = this.props;
          return (
            <ul>
              <li>姓名:{name}</li>
              <li>性别:{sex}</li>
              <li>年龄:{age + 1}</li>
            </ul>
          );
        }
      }
ReactDOM.render(<Person name="tom" age={18} sex="男" onSuccess={onSuccess}/>, document.getElementById("root1"));
      // 批量传递 props 【{...x}】
      const backData = { name: '后端返回数据', age: 19, sex: "女" }; 
ReactDOM.render(<Person {...backData} />, document.getElementById("root2"));
ReactDOM.render(<Person name="jack" age={20}/>, document.getElementById("root3"));
      function onSuccess() {
        console.log('执行事件');
      }
    </script>

函数组件Props

      function Person(props) {
        const { name, age, sex } = props;
        return (
          <ul>
            <li>姓名:{name}</li>
            <li>性别:{sex}</li>
            <li>年龄:{age + 1}</li>
          </ul>
        );
      }
      Person.propTypes = {
        name: PropTypes.string.isRequired, 
        sex: PropTypes.string,
        age: PropTypes.number,
      };
ReactDOM.render(<Person name='tom' age={18} sex="男" />, document.getElementById("root"));

总结:

(1)、组件标签的所有属性都保存在props中,但是组件内部不要修改props数据;

(2)、批量传递:{...item}、类型检查:PropTypes、默认属性:defaultProps

1.4.3、refs

class MyComponent extends React.Component {
        showData = () => {
          const { input1 } = this.refs;
          alert(input1.value);
        };
        showData2 = () => {
          const { input2 } = this;
          alert(input2.value);
        };
        myRef=React.createRef();
        showData3 = () => {
          alert(this.myRef.current.value);
        };
render() {
          return (
            <div>
              {/* 1、字符串形式 */}
              <input ref="input1" type="text" placeholder="点击按钮提示数据" />
              &nbsp;
              <button onClick={this.showData}>点击提示左侧数据</button>&nbsp;
              {/* 2、回调函数形式 */}
              <input
                ref={(c) => (this.input2 = c)}
                onBlur={this.showData2}
                type="text"
                placeholder="失去焦点提示数据"
              />&nbsp;
              {/* 3、createRef API:存储被ref标识的节点,“专人专用” */}
              <input
                ref={this.myRef}
                onBlur={this.showData3}
                type="text"
                placeholder="createRef的使用"
              />
            </div>
          );
        }
}
ReactDOM.render(<MyComponent />, document.getElementById("root"));

总结:

(1)、直接访问和操作DOM元素或React组件实例;

(2)、使用React.createRef()或者回调函数形式(类组件);使用useRef(函数组件)

1.5、事件处理

总结:

(1)、通过onXxx属性指定事件处理函数,事件通过事件委托【委托给组件最外层的元素】处理的;

(2)、通过event.target得到发生事件的DOM元素对象【高效】;

(3)、原生Js事件使用onclick,而React事件使用onClick【为了更好的兼容性】。

1.6、收集表单数据—非受控组件和受控组件

特性受控组件 (Controlled)非受控组件 (Uncontrolled)
值存储位置存储在React组件的state存储在DOM中(使用ref访问)
表单元素控制React通过state控制表单的值浏览器控制,React不干涉
更新方式用户输入时通过onChange更新state使用ref获取值,无需触发事件
适用场景需要表单验证、交互或复杂逻辑时简单表单,且无需与React状态紧密交互
代码复杂度稍微复杂,需要维护状态和事件处理简单,直接使用ref访问DOM

1.7、高阶函数—函数柯里化

总结:

高阶函数:如果函数的参数或者返回值是函数,那么这个函数就是高阶函数。

      常见有:Promise、setTimeout、arr.map()、call、apply、bind、...

函数柯里化:通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的一种函数编码形式。·

或者:直接在视图上使用箭头函数,同时传入属性值和对应的event。

1.8、生命周期—新旧对比

1.8.1、旧16+

  <script type="text/babel">
    class MyComponent extends React.Component {
      constructor(props) {
        console.log("构造器---constructor");
        super(props);
        this.state = { count: 0 };
      }
      componentWillMount() {
        console.log("组件将要挂载---componentWillMount");
      }
      componentDidMount() {
        console.log("组件挂载完毕---componentDidMount");
      }
      shouldComponentUpdate(nextProps, nextState) {
        console.log("组件是否需要更新---shouldComponentUpdate");
        return true;
      }
      componentWillUpdate() {
        console.log("组件将要更新---componentWillUpdate");
      }
      componentDidUpdate() {
        console.log("组件更新完毕---componentDidUpdate");
      }
      componentWillUnmount() {
        console.log("组件即将卸载---componentWillUnmount");
      }
      moveIt = () => {
        ReactDOM.unmountComponentAtNode(document.getElementById("root")); //卸载
      };
      addIt = () => {
        const { count } = this.state;
        this.setState({ count: count + 1 });
      };
      forceIt = () => {
        this.forceUpdate();
      };
      render() {
        console.log("挂载页面---render");
        const { count } = this.state;
        return (
          <div>
            <h2>当前求和为:{count}</h2>
            <button onClick={this.addIt}>点击+1</button>
            <button onClick={this.moveIt}>销毁</button>
            <button onClick={this.forceIt}>强制更新</button>
          </div>
        );
      }
    }
    // A和B是父子关系
    class A extends React.Component {
      state = { carName: '奔驰' };
      changeCar = () => {
        this.setState({ carName: '宝马' });
      };
      render() {
        return (
          <div>
            <div>A页面</div>
            <button onClick={this.changeCar}>换车</button>
            <B carName={this.state.carName} />
          </div>
        );
      }
    }
    class B extends React.Component {
      componentWillReceiveProps(nextProps) {
        console.log('B组件接收到新的属性(第一次不调)', nextProps);
      }
      render() {
        return <div>B组件接收的车是:{this.props.carName}</div>;
      }
    }
    // ReactDOM.render(<MyComponent />, document.getElementById("root"));
    ReactDOM.render(<A />, document.getElementById("root"));
  </script>

1.8.2、新17+

    static getDerivedStateFromProps(props,state) {
        console.log("获取新的属性---getDerivedStateFromProps",props,state);
        return null;//返回null或者props
      }
    ReactDOM.render(<MyComponent count={199} />, document.getElementById("root"));
<style>
    .list {
      width: 200px;
      height: 150px;
      background-color: skyblue;
      overflow: auto;
    }
    .news {
      height: 30px;
</style>
class MyComponent extends React.Component {
      state = { newArr: [] }
      componentDidMount() {
        setInterval(() => {
          const { newArr } = this.state
          const news = '新闻' + (newArr.length + 1)
          this.setState({ newArr: [news, ...newArr] })
        }, 1000);
      }
      getSnapshotBeforeUpdate(prevProps, prevState) {
        return this.refs.list.scrollHeight;// 获取更新前的DOM节点
      }
      componentDidUpdate(prevProps, prevState, snapshot) {
        this.refs.list.scrollTop += this.refs.list.scrollHeight - snapshot;
      }
      render() {
        return <div className="list" ref="list">
          {
            this.state.newArr.map((item, index) => {
              return <div className="news" key={index}>{item}</div>
            })
          }</div>;
      }
}

1.8.3、对比

17+在16+的基础上新增了getDerivedStateFromPropsgetSnapshotBeforeUpdate

即将废弃 componentWillMount、componentWillReceiveProps、componentWillUpdate三个钩子。

1.9、DOM的Diffing算法

经典面试题:为啥key不能使用index,而是取id(唯一标识)

总结:
1、使用 index 作为 key
        在列表项的顺序发生变化、增加或删除时,可能会导致错误渲染或状态丢失
        适用于列表项不变,且不涉及删除、增加或排序操作的简单情况。
2、使用 id 作为 key
        更稳定,能够确保元素在更新时保持一致,特别是在列表顺序发生变化时。
       尤其是在动态数据列表(增、删、改、排序等操作)中使用。

二、脚手架搭建

2.1、创建项目

1、全局安装:npm i -g create-react-app【查看是否下载create-react-app --version

2、切换到想创建项目的目录下:create-react-app react_app【Node版本在14+及以上】

3、进入项目文件夹:cd react_app

4、启动项目:npm start【修改package.json,重新下载node_modules、 package-lock.json来修改版本

或者直接用:React--Umi和Dva_react dva-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2296382.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

51单片机(国信长天)矩阵键盘的基本操作

在CT107D单片机综合训练平台上&#xff0c;首先将J5处的跳帽接到1~2引脚&#xff0c;使按键S4~S19按键组成4X4的矩阵键盘。在扫描按键的过程中&#xff0c;发现有按键触发信号后(不做去抖动)&#xff0c;待按键松开后&#xff0c;在数码管的第一位显示相应的数字:从左至右&…

STM32 RTC亚秒

rtc时钟功能实现&#xff1a;rtc模块在stm32内部&#xff0c;由电池或者主电源供电。如下图&#xff0c;需注意实现时仅需设置一次初始化。 1、stm32cubemx 代码生成界面设置&#xff0c;仅需开启时钟源和激活日历功能。 2、生成的代码,需要对时钟进行初始化&#xff0c;仅需…

【Linux】深入理解linux权限

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;Linux 目录 前言 一、权限是什么 二、用户和身份角色 三、文件属性 1. 文件属性表示 2. 文件类型 3. 文件的权限属性 四、修改文件的权限属性和角色 1. …

json格式,curl命令,及轻量化处理工具

一. JSON格式 JSON&#xff08;JavaScript Object Notation&#xff09; 是一种轻量级的数据交换格式。它基于一个子集的JavaScript编程语言&#xff0c;使用人类易于阅读的文本格式来存储和表示数据。尽管名字中有“JavaScript”&#xff0c;但JSON是语言无关的&#xff0c;几…

web直播弹幕抓取分析 signature

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 前言 最近遇到太多难点了卡了很久&am…

ABP框架9——自定义拦截器的实现与使用

一、AOP编程 AOP定义:面向切片编程&#xff0c;着重强调功能&#xff0c;将功能从业务逻辑分离出来。AOP使用场景&#xff1a;处理通用的、与业务逻辑无关的功能&#xff08;如日志记录、性能监控、事务管理等&#xff09;拦截器:拦截方法调用并添加额外的行为&#xff0c;比如…

CUDA 计算平台 CUDA 兼容性【笔记】

在 b 站看过的两个关于 CUDA 的技术分享&#xff0c;整理分享下对自己有用的课件。 20231130 2023第9期 聊一聊常见的AI计算平台库_哔哩哔哩_bilibili20230831 2023第6期 聊一聊CUDA兼容性_哔哩哔哩_bilibili 文章目录 CUDA 计算平台CUDA 函数库介绍英伟达三大护城河&#xff1…

最新消息 | 德思特荣获中国创新创业大赛暨广州科技创新创业大赛三等奖!

2024年12月30日&#xff0c;广州市科技局公开第十三届中国创新创业大赛&#xff08;广东广州赛区&#xff09;暨2024年广州科技创新创业大赛决赛成绩及拟获奖企业名单&#xff0c;德思特获得了智能与新能源汽车初创组【第六名】【三等奖】的好成绩&#xff01; 关于德思特&…

ubuntu安装VMware报错/dev/vmmon加载失败

ubuntu安装VMware报错/dev/vmmon加载失败&#xff0c;解决步骤如下&#xff1a; step1&#xff1a;为vmmon和vmnet组件生成密钥对 openssl req -new -x509 -newkey rsa:2048 -keyout VMW.priv -outform DER -out VMW.der -nodes -days 36500 -subj "/CNVMware/"ste…

python的列表、元组、深拷贝、浅拷贝(四)

python的列表 一、序列1. 序列定义2. 序列数据类型包括3.特点&#xff1a;都支持下面的特性 二、 列表1. 列表的创建2. 列表的基本特性(1) 连接操作符喝重复操作符(2) 成员操作符&#xff08;in , not in &#xff09;(3) 索引(4) 切片练习(5) for循环 3. 列表的常用方法(1) 一…

2.10作业

思维导图 C C语言

【深度学习】多目标融合算法(四):多门混合专家网络MMOE(Multi-gate Mixture-of-Experts)

目录 一、引言 二、MMoE&#xff08;Multi-gate Mixture-of-Experts&#xff0c;多门混合专家网络&#xff09; 2.1 技术原理 2.2 技术优缺点 2.3 业务代码实践 2.3.1 业务场景与建模 2.3.2 模型代码实现 2.3.3 模型训练与推理测试 2.3.4 打印模型结构 三、总结 一、…

RuoYi-Vue-Oracle的oracle driver驱动配置问题ojdbc8-12.2.0.1.jar的解决

RuoYi-Vue-Oracle的oracle driver驱动配置问题ojdbc8-12.2.0.1.jar的解决 1、报错情况 下载&#xff1a;https://gitcode.com/yangzongzhuan/RuoYi-Vue-Oracle 用idea打开&#xff0c;启动&#xff1a; 日志有报错&#xff1a; 点右侧m图标&#xff0c;maven有以下报误 &…

C# OpenCV机器视觉:对位贴合

在热闹非凡的手机维修街上&#xff0c;阿强开了一家小小的手机贴膜店。每天看着顾客们自己贴膜贴得歪歪扭扭&#xff0c;不是膜的边缘贴不整齐&#xff0c;就是里面充满了气泡&#xff0c;阿强心里就想&#xff1a;“要是我能有个自动贴膜的神器&#xff0c;那该多好啊&#xf…

Baumer工业相机堡盟相机的相机传感器芯片清洁指南

Baumer工业相机堡盟相机的相机传感器芯片清洁指南 Baumer工业相机1.Baumer工业相机传感器芯片清洁工具和清洁剂2.Baumer工业相机传感器芯片清洁步骤2.1、准备步骤2.2、清洁过程1.定位清洁工具2.清洁传感器3&#xff0e;使用吹风装置 Baumer工业相机传感器芯片清洁的优势设计与结…

《我在技术交流群算命》(三):QML的Button为什么有个蓝框去不掉啊(QtQuick.Controls由Qt5升级到Qt6的异常)

有群友抛出类似以下代码和运行效果截图&#xff1a; import QtQuick import QtQuick.ControlsWindow {width: 640height: 480visible: truetitle: qsTr("Hello World")Button{anchors.centerIn: parentwidth: 100height: 40background: Rectangle {color: "red…

Golang:Go 1.23 版本新特性介绍

流行的编程语言Go已经发布了1.23版本&#xff0c;带来了许多改进、优化和新特性。在Go 1.22发布六个月后&#xff0c;这次更新增强了工具链、运行时和库&#xff0c;同时保持了向后兼容性。 Go 1.23 的新增特性主要包括语言特性、工具链改进、标准库更新等方面&#xff0c;以下…

在 PyTorch 中理解词向量,将单词转换为有用的向量表示

你要是想构建一个大型语言模型&#xff0c;首先得掌握词向量的概念。幸运的是&#xff0c;这个概念很简单&#xff0c;也是本系列文章的一个完美起点。 那么&#xff0c;假设你有一堆单词&#xff0c;它可以只是一个简单的字符串数组。 animals ["cat", "dog…

deepseek API 调用-python

【1】创建 API keys 【2】安装openai SDK pip3 install openai 【3】代码&#xff1a; https://download.csdn.net/download/notfindjob/90343352

Git、Github和Gitee完整讲解:丛基础到进阶功能

第一部分&#xff1a;Git 是什么&#xff1f; 比喻&#xff1a;Git就像是一本“时光机日记本” 每一段代码的改动&#xff0c;Git都会帮你记录下来&#xff0c;像是在写日记。如果出现问题或者想查看之前的版本&#xff0c;Git可以带你“穿越回过去”&#xff0c;找到任意时间…