React基础学习(一)

news2025/2/21 11:24:03

一、虚拟DOM和真实DOM

<script type="text/babel"> // 此处一定要写babel!!!!!!!
   // 1. 创建虚拟DOM
   // const VDOM = <h1 id="title">Hello, React!</h1> // 此处一定不要写引号 因为这不是字符串!!!!!!!
   const VDOM = ( // 如果有多层嵌套,使用jsx更加方便快捷 更为符合开发方式
       <h1 id="title">
           <span>Hello, React!</span>
       </h1>
   )

   // 2. 渲染虚拟DOM 参数:虚拟DOM、容器
   ReactDOM.render(VDOM, document.getElementById('box'))


   // ----------------------------------------------------
   const TDOM = document.getElementById('test')
   console.log('虚拟DOM', VDOM) // Object
   console.log('真实DOM', TDOM) // <div id="test"></div>
   debugger;
	
</script>
关于虚拟DOM:
  1. 本质是Object对象(一般对象)
  2. 虚拟DOM比较“轻”(属性和方法少),真实DOM比较“重”(属性和方法多),因为虚拟DOM是React内部在用,无需真实DOM上那么多属性
  3. 虚拟DOM最终都会被React转换为真实DOM,最终呈现在页面。

二、jsx的语法规则

  1. 定义虚拟DOM时,不要用引号
  2. 标签中混入js表达式时,使用{}
  3. 样式的类名指定不能用class,要使用className,因为要与es6中的关键字类(class)做区分
  4. 内联样式,要使用{{key:value}}的形式去写,外层{}表示里边的内容为js,内层{}表示对象
  5. 只能有一个根标签
  6. 标签必须闭合
  7. 标签首字母:
    1)首字母小写开头,则将该标签转为html中的同名元素,若html中无与之对应的同名元素,则报红色警告
    2)首字母大写开头,react会去渲染对应的组件,若组件没有定义,则报错。
<script type="text/babel">
     const myId = 'container'
     const myData = 'Hello, React'
     // 创建虚拟DOM
     const VDOM = (
         <div>
             <h1 className="title" id={myId}>
                 <span style={{color: 'white'}}>{myData}</span>
             </h1> 
             <h1 className="title" id={myId+'2'}>
                 <span style={{color: 'white'}}>{myData}</span>
             </h1> 
             <good>222</good>   // 无与之对应的html标签 会报警告
             // <Good>333</Good>   // 报错 首字母大写表示使用的是组件 Good组件未定义
         </div>
     )
     // 渲染虚拟DOM到页面
     ReactDOM.render(VDOM, document.getElementById('box'))
 </script>

三、组件实例的三大属性

  1. state
<script type="text/babel">
    // 1.创建一个组件
    class Weather extends React.Component {
        
        // 构造器调用几次?------一次
        constructor(props) {
            console.log('constructor')

            super(props)
            // 初始化状态
            // 给state添加属性 就需要在组件实例初始化时赋值
            this.state = {isHot: false, wind: '微风'}
            // 解决changeWeather中this指向问题
            this.changeWeather = this.changeWeather.bind(this)

            // 【this指向问题解释】实际上也可以这么写:
            // 右边的this.changeWeather.bind(this):this指向Weather实例对象,改变(bind)原型对象上changeWeather方法的this指向为 Weather实例对象
            // 左边的this.demo:this指向Weather实例对象,表示初始化给实例对象一个名为demo的方法
            // 把右边的表达式赋值给左边
            // this.demo = this.changeWeather.bind(this)
        }

        // render调用几次?----1+n次,1是初始化调用1次,n是状态更新的次数
        render() {
            console.log('render')

            // 读取状态
            let {isHot, wind} = this.state
            // console.log(this) // this指向的是 Weather 组件实例,state是组件实例的属性 
            // react中的点击事件为onClick(原生为onclick)
            // 此处不使用changeWeather()的原因是:页面一加载时就执行了onClick={changeWeather},相当于直接执行了changeWeather函数体中的内容,所以使用changeWeather 相当于是把changeWeather函数赋值给onClick事件
            return <h1 onClick={this.changeWeather}>今天天气很{isHot ? '炎热' : '寒冷'}{wind}</h1>
            
            // 【this指向问题解释】实际上也可以这么写:
            // 调用的并不是原型对象上的changeWeather,而是初始化时实例对象上的名为demo的方法
            // return <h1 onClick={this.demo}>今天天气很{isHot ? '炎热' : '寒冷'}</h1>
        }

        // changeWeather调用几次?------点几次调几次
        changeWeather() {
            console.log('changeWeather')

            // changeWeather放在了 类Weather的原型对象 上,供实例使用
            // 由于changeWeather作为onClick的回调,所以不是通过实例调用的,是直接调用
            // 类中的方法默认开启了严格模式,所以changeWeather中的this指向为undefined
            // console.log(this)


            const isHot = this.state.isHot
            // 【严重注意】:状态必须要通过setState进行更新,且更新是合并(只更新setState中传入的属性),不是替换(setState中其他未传入的属性不会被删除)。
            this.setState({isHot: !isHot})

            // 【严重注意】:状态(state)不可直接更改,下面这行就是直接更改!!!
            // this.state.isHot = !isHot   // 这是错误的!!!

        }
    }
    // 2.渲染到页面
    ReactDOM.render(<Weather/>, document.getElementById('box'))

</script>
简写方式
<script type="text/babel">
     // 1.创建一个组件
     class Weather extends React.Component {
         // 初始化状态
         // 给Weather的实例对象上直接添加state属性
         state = {isHot: false, wind: '微风'}

         render() {
             let {isHot, wind} = this.state
             return <h1 onClick={this.changeWeather}>今天天气很{isHot ? '炎热' : '寒冷'}{wind}</h1>
         }

         // 自定义方法----使用赋值语句+箭头函数 替代bind方法
         changeWeather = () => {
             const isHot = this.state.isHot
             this.setState({isHot: !isHot})
         }
     }
     // 2.渲染到页面
     ReactDOM.render(<Weather/>, document.getElementById('box'))

 </script>
  1. props
<script type="text/babel">
    // 创建组件
    class Person extends React.Component {
        render() {
            const {name, age, gender} = this.props
            return (
                <ul>
                    <li>姓名:{name}</li>
                    <li>性别:{age}</li>
                    <li>年龄:{gender}</li>
                </ul>
            )
        }
    }

    // 渲染组件到页面
    ReactDOM.render(<Person name="tom" age="28" gender="男"/>, document.getElementById('box1'))

    // ReactDOM.render(<Person name="daisy" age="20" gender="女"/>, document.getElementById('box2'))

    const p = {name: 'daisy', age: '21', gender: "女"}
    // ReactDOM.render(<Person name={p.name} age={p.age} gender={p.gender}/>, document.getElementById('box2'))
    // 下面这种写法(...p)是上面这种写法的语法糖,在组件中的{...p}---{}表示的是里边要写js语句了 并不是对象的意思
    // 在react和babel的共同作用下,是允许使用展开运算法展开一个对象(...p是被允许的)
    ReactDOM.render(<Person {...p}/>, document.getElementById('box2'))
</script>
简写方式
<script type="text/babel">
    // 创建组件
    class Person extends React.Component {
        // 对标签属性进行必要性以及类型限制
        static propTypes = {
            name: PropTypes.string.isRequired, // 限制name必传,且为string类型
            age: PropTypes.number, // 限制age为number类型
            gender: PropTypes.string, // 限制gender为string类型
        }

        // 指定标签属性默认值
        static defaultProps= {
            age: 10, // age默认为10
            gender: '男' // gender默认为男
        }

        render() {
            const {name, age, gender} = this.props
            // props是只读的
            // this.props.name = 'jerry'   // 会报错,因为props是只读的

            return (
                <ul>
                    <li>姓名:{name}</li>
                    <li>年龄:{age + 1}</li>
                    <li>性别:{gender}</li>
                </ul>
            )
        }
    }

    // 渲染组件到页面
    ReactDOM.render(<Person name="tom"/>, document.getElementById('box1'))
</script>
函数式组件使用props
<script type="text/babel">
     // 创建组件
     function Person(props) {
         const {name, age, gender} = props
         return (
             <ul>
                 <li>姓名:{name}</li>
                 <li>年龄:{age + 1}</li>
                 <li>性别:{gender}</li>
             </ul>
         )
     }

     // 对标签属性进行必要性以及类型限制
     Person.propTypes = {
         name: PropTypes.string.isRequired, // 限制name必传,且为string类型
         age: PropTypes.number, // 限制age为number类型
         gender: PropTypes.string, // 限制gender为string类型
     }

     // 指定标签属性默认值
     Person.defaultProps= {
         age: 10, // age默认为10
         gender: '男' // gender默认为男
     }
     
     // 渲染组件到页面
     ReactDOM.render(<Person name="tom"/>, document.getElementById('box1'))
 </script>
  1. ref
<script type="text/babel">
    //创建组件
    class Demo extends React.Component{
        // React.createRef 调用后返回一个容器,该容器可以存储被ref所标识的节点,该容器是“专人专用”
        myRef = React.createRef()
        myRef2 = React.createRef()

        // 展示左侧数据
        showData = () => {
            alert(this.myRef.current.value)
        }

        // 展示右侧数据
        showData2 = () => {
            alert(this.myRef2.current.value)
        }

        render() {
            return (
                <div>
                    <input ref={this.myRef} type="text" placeholder="点击按钮提示数据" />&nbsp;
                    <button onClick={this.showData}>点我提示左侧数据</button>&nbsp;
                    <input ref={this.myRef2} type="text" placeholder="失去焦点提示数据" onBlur={this.showData2}/>
                </div>
            )
        }
    }

    // 渲染组件到页面
    ReactDOM.render(<Demo/>, document.getElementById('box'))
</script>

四、事件处理

<script type="text/babel">
   //创建组件
    class Demo extends React.Component{
        // 创建ref容器
        myRef = React.createRef()
        myRef2 = React.createRef()

        // 展示左侧数据
        showData = () => {
            alert(this.myRef.current.value)
        }

        // 展示右侧数据
        showData2 = (event) => {
            alert(event.target.value)
        }

        render() {
            return (
                <div>
                    <input ref={this.myRef} type="text" placeholder="点击按钮提示数据" />&nbsp;
                    <button onClick={this.showData}>点我提示左侧数据</button>&nbsp;
                    <input type="text" placeholder="失去焦点提示数据" onBlur={this.showData2}/>
                </div>
            )
        }
    }

    // 渲染组件到页面
    ReactDOM.render(<Demo/>, document.getElementById('box'))
</script>
事件处理总结:
  1. 通过onXxx属性指定事件处理函数(注意大小写)
    a)React使用的是自定义(合成)事件,而不是使用的原生DOM事件 ----为了更好的兼容性
    b)React中的事件是通过事件委托方式处理的(委托给组件最外层的元素) ---- 为了更高效
  2. 通过event.target得到发生事件的DOM元素对象 ---- 不要过度使用ref

五、组件的生命周期(详细代码在下一篇笔记)

旧版与新版对比图示:

react生命周期对比图

附:使用html学习React基础代码

<!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>demo</title>
</head>
<body>
    <!-- 准备好一个容器 -->
    <div id="box"></div>

    <!-- 引入react核心库 -->
    <script type="text/javascript" src="https://unpkg.com/react@16/umd/react.development.js"></script> 
    <!-- 引入react扩展库 -->
    <script type="text/javascript" src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <!-- 引入babel,用于将jsx转换为js -->
    <script type="text/javascript" src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <!-- 引入prop-types,用于对组件标签的限制 -->
    <script type="text/javascript" src="../../../js/prop-types/prop-types.js"></script>


    <script type="text/babel">
      
    </script>
    
</body>
</html>

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

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

相关文章

PostgreSQL15.2最新版本安装_远程连接_Navicat操作_pgAdmin操作_Windows10上安装---PostgreSQL工作笔记001

首先去下载postgresql https://www.enterprisedb.com/downloads/postgres-postgresql-downloads 下载地址: 去上面的地址下载,最好下载10版本的,我这里下载的是15版本的,有问题,后面说吧 下载以后 然后双击安装 next 选择目录next next 输入密码next

好程序员:Java线下培训有必要吗?零基础想学Java怎么学?

有粉丝问好程序员&#xff1a;自己只有周末有时间&#xff0c;想报班学习Java编程&#xff0c;是线上学编程好还是线下学编程好&#xff1f;小源从实际客观以及学习效果的角度来讲&#xff0c;毫无疑问是线下学编程的效果会更好。为什么这样说呢&#xff1f; 比如&#xff1a;家…

初探强化学习

1.引言 人生中充满选择&#xff0c;每次选择就是一次决策&#xff0c;我们正是从一次次决策中&#xff0c;把自己带领到人生的下一段旅程中。在回忆往事的时候&#xff0c;我们会对生命中某些时刻的决策印象深刻&#xff1a;“还好当时选择了读研&#xff0c;毕业后找到了一份自…

学习小程序基础内容之逻辑交互

我们先来看一下实现的效果。 然后再来分享结构。 结构分为左右3:7 分配&#xff0c; 左侧是类别&#xff0c;右侧是该类别对应的品牌。 后台会在onload的请求把左侧的类别返回来&#xff0c;然后我们通过循环把数据展示出来。然后通过点击事件&#xff0c;把对应的品牌请求回来…

2023年,初级测试到高级测试开发工程师需要什么技能?卷起来......

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Python自动化测试&…

泵站水闸自动化系统调试方案

1、调试方案概述 调试方案分为自控系统现场调试、视频系统现场调试以及控制中心远程调试&#xff08;包含通讯测试、自控调试和视频调试&#xff09;。 自控系统现场调试分为触摸屏调试和本地上位机调试两部分。触摸屏系统的调试步骤如下&#xff1a; 确认触摸屏和PLC的通讯情…

C++标准库 -- 泛型算法 (Primer C++ 第五版 · 阅读笔记)

C标准库 -- 泛型算法 (Primer C 第五版 阅读笔记&#xff09; 第10章 泛型算法------(持续更新)10.1、概述10.2、初识泛型算法10.2.1、只读算法10.2.2、写容器元素的算法10.2.3、重排容器元素的算法 10.3、定制操作10.4、再探迭代器10.5、泛型算法结构10.6、特定容器算法 第10…

【ubuntu】将硬盘挂载到指定目录并设置开机自动挂载

最近打算将数据盘开机自动挂载&#xff0c;省得每次都要手动挂载&#xff0c;总结步骤如下&#xff1a; 输入以下命令&#xff0c;将系统中所有的分区都列出来&#xff1a; sudo fdisk -l找到你要挂载的分区&#xff0c;可以通过容量大小分辨&#xff0c;当然&#xff0c;有可…

黑马Mysql从入门到高级

文章目录 1. 数据库基础1.1 基础概念1.2 SQL1.2.1 语法1.2.2 数据类型1.2.3 DDL&#xff08;definition&#xff09; 1.3 函数1.3.1 字符串函数1.3.2 日期函数1.3.3 数字函数1.3.4 流程函数 1.4 约束1.5 多表查询1.5.1 连接1.5.2 联合查询 2. 数据库进阶2.1 存储引擎2.1.1 Inno…

中国人民大学与加拿大女王大学金融硕士——学习的阶段让未来的人生更丰盈

初入职场的新人拥有同样的起跑线&#xff0c;经过时间的沉淀&#xff0c;每个人之间就会有差距。差距是怎样被拉开的呢&#xff1f;也可以说是行动导致的。毕竟想是问题&#xff0c;去做才是答案&#xff0c;有行动才会有结果。在职读研与其停留在想的阶段&#xff0c;不如去准…

我发现了PMP通关密码!这14页纸直接背!

一周就能背完的PMP考试技巧只有14页纸 共分成了4大模块 完全不用担心看不懂 01关键词篇 第1章引论 1.看到“驱动变革”--选项中找“将来状态” 2.看到“依赖关系”--选项中找“项目集管理” 3.看到“价值最大化”--选项中找“项目组合管理” 4.看到“可行性研究”--选项中…

「线性DP-步入」最长上升子序列(LIS)

题目描述 给定一个长度为 N 的数列&#xff0c;求数值严格单调递增的子序列的长度最长是多少。 输入格式 第一行包含整数 N。 第二行包含 N 个整数&#xff0c;表示完整序列。 输出格式 输出一个整数&#xff0c;表示最大长度。 数据范围 1 ≤ N ≤ 1000 1≤N≤1000 1≤…

【进阶C语言】有关动态内存管理的经典笔试题(详细图文讲解)

前言 &#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;致力于C/C、Java、Python等多编程语言&#xff0c;热爱跑步&#xff0c;喜爱音乐的一位博主。 &#x1f4d7;本文收录于C语言进阶系列&#xff0c;本专栏主要内容为数据的存储、指针的进阶、字符串和内存函数…

.class文件在线转成.java文件方法

使用背景&#xff1a; 工作中碰到老的项目就头疼&#xff0c;有些连源码都没有&#xff0c;解决bug只能从class文件反编译成java后&#xff0c;来读懂业务逻辑。 后来在网上找了一些工具来帮助class文件转码&#xff0c;有些遇到lamda表达式就转换错误&#xff0c;有些使用起…

正则表达式的字符串取反常用正则表达式

正则表达式的字符串取反操作 文件同步时&#xff0c;想要过滤掉扩展名为.tmp或者.TMP的临时文件&#xff0c;想要使用正则表达式对字符串进行取反操作。 注意&#xff1a;[^tmp]* 这种取反的表达式&#xff0c;只能表示匹配除了t、m、p以外的所有字符&#xff0c;是单字符匹配…

gRPC-Go源码解读三 服务端处理流程分析

相较于Client端的复杂处理流程&#xff0c;Server端相对来说简单了很多&#xff0c;核心就是创建个TCP套接字并监听&#xff0c;收到客户端连接请求则起个go协程处理&#xff0c;子协程根据请求中的服务名和方法名调用对应的服务方法处理&#xff0c;处理完成之后则返回响应。整…

叫板IT部门和专业软件公司,低代码成为企业数字化的新选择

从2017年政府将“数字经济”写入工作报告&#xff0c;到今年两会将企业数字化转型列为重点议题&#xff0c;数字化的口号已喊了6年。政策对于数字化的支持越来越坚定&#xff0c;令人欣喜的是&#xff0c;越来越多具有远见卓识的企业已将数字化建设作为工作重心。 然而&#xf…

【LeetCode】剑指 Offer 60. n个骰子的点数 p294 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/nge-tou-zi-de-dian-shu-lcof/ 1. 题目介绍&#xff08;60. n个骰子的点数&#xff09; 把n个骰子扔在地上&#xff0c;所有骰子朝上一面的点数之和为 s。输入 n&#xff0c;打印出 s 的所有可能的值出现的概率。 你需要用一…

Vue.js条件渲染指令v-if及v-show

目录 一、v-if 二、v-show 三、v-if与v-show的选择 一、v-if v-if是Vue.js的条件语句&#xff0c;v-if指令用于条件性地渲染一块内容&#xff0c;这块内容只会在指令的表达式返回true的时候被渲染。需要特别注意的是&#xff0c;v-if所关联的是Vue.js的动态变量。 v-if的使用…

如何计算连续变量的熵

背景 做特征选择时&#xff0c;有时候会用到计算特征的信息熵&#xff0c;可是离散的好计算&#xff0c;但连续的呢&#xff1f;按照把连续变量离散的方法设置阈值点吗&#xff1f;好像比较麻烦&#xff0c;需要排序&#xff0c; 计算阈值。没有能自动的方法吗&#xff1f; 找…