零基础入门一文带你了解前端React中组件的使用

news2024/9/25 1:24:44

目录

一、React 组件介绍

二、创建React组件的两种方式

1. 使用函数创建组件

2. 使用类创建组件

3. 抽离为独立 JS文件

三、React 事件处理

1. 事件绑定

2. 事件对象

四、有状态组件与无状态组件

1. state的基本使用

2. setState() 修改状态 

3. 从 JSX 中抽离事件处理程序

4. 事件绑定 this 指向

4.1. 箭头函数

4.2. Function.prototype.bind()

4.3. class 的实例方法

五、表单处理

1. 受控组件

1.1 概念

1.2 实现步骤

1.3  多表单元素优化

2. 非受控组件


一、React 组件介绍

  • 组件是 React 的一等公民,使用React其实就是在使用组件。
  • 组件表示页面中的部分功能。
  • 组合多个组件实现完整的页面功能。
  • 特点:可复用、独立、可组合

二、创建React组件的两种方式

1. 使用函数创建组件

  • 函数组件:使用 JS 的函数(或箭头函数)创建的组件。
    function Hello(){
         return {
           <div> 函数组件 </div>
      }
    }

注意:

  1. 函数名称必须以大写字母开头。
  2. 函数组件必须有返回值,表示该组件的结构。
  3. 如果返回值为null,表示不渲染任何内容。
  •  渲染函数组件:用函数名作为组件标签名,组件标签可以是单标签也可以是双标签。
    const Hello = () => <div> 函数组件 </div>
    
    // 渲染
    ReactDOM.render(<Hello />,document.getElementById('root'))

2. 使用类创建组件

  • 类组件:使用 ES6 的 class创建的组件
    class Hello extends React.Component {
        render(){
              return <div> 类组件 </div>
       }
    }
    ReactDOM.render(<Hello />,document.getElementById('root'))

 注意:

  1. 类名称也必须以大写字母开头
  2. 类组件应该继承 React.Component 父类,从而可以使用父类中提供的方法或属性。
  3. 类组件必须提供 render() 方法
  4. render() 方法必须有返回值,表示该组件的结构。

3. 抽离为独立 JS文件

思考:项目中组件多了之后,我们该如何组织这些组件呢?

  • 选项一:将所有组件放在同一个JS文件中
  • 选项二:将每个组件放到单独的JS文件中(✔)
  1. 创建 Hello.js 组件
  2. 在 Hello.js 中导入React
  3. 创建组件(函数 或 类)
  4. 在 Hello.js 中导出该组件
  5. 在 index.js 中导入 Hello 组件
  6. 渲染组件
// Hello.js
import React from 'react'
class Hello extends React.Component {
  render() {
        return <div> 组件 </div> 
   }
}
// 导出 Hello 组件
export default Hello

// index.js
import Hello from './Hello' 
// 渲染导入的 Hello组件
ReactDOM.render(<Hello />,root)

三、React 事件处理

1. 事件绑定

  • React 事件绑定语法与DOM事件语法相似
  • 语法:on + 事件名称 = { 事件处理程序 }例如:onClick = { () => {} }
  • 注意:React 事件采用驼峰命名法,比如:onMouseEnter、onFocus
.// 类组件
class App extends React.Component {
  handleClick() {
      console.log('单击事件')
   }
  render() {
       return {
            <button onclick={this.handleClick} ><button>
       }
   }
}

// 函数组件
fucntion App() {
     function handleClick() {
       console.log('点击事件')
  }
      return {
            <button onclick={handleClick} ><button>
   }
}

2. 事件对象

  • 可以通过事件处理程序的参数获取到事件对象。
  • React中的事件对象叫做:合成事件(对象)。
  • 合成事件:兼容所有浏览器,无需担心跨浏览器兼容性问题。
function handleClick(e) {
    // 阻止浏览器的默认行为
    e.preventDefault () 
    console.log('事件对象',e)
}
<a href="www.baidu.com" onClick={handleClick}>点击</a>

四、有状态组件与无状态组件

  • 函数组件又叫做无状态组件,类组件又叫做有状态组件
  • 状态(state)即数据,函数组件没有自己的状态,只负责数据展示(静),类组件有自己的状态,负责更新UI,让页面“动”起来。

比如计数器案例中,点击按钮让数值加1。0 和 1 就是不同时刻的状态,而由0 变 1 就表示状态发生了变化。状态变化后,UI也要相应的更新。React 中想要实现该功能,就要使用有状态组件来实现。

1. state的基本使用

  • 状态(state)即数据,是组件内部的私有数据,只能在组件内部使用。
  • state的值是对象,表示一个组件中可以可以有多个数据。
    class App extends React.Component {
      constructor() {
            super()
            // 初始化 state
            this.state = {
                count: 0
          }
       }
         // ES6 简化语法 初始化state
         state = {
            count : 0
             }
       render() {
             return {
            <div> 计数器 </div>
          }
       }
    }
    
    ReactDOM.render(<App />,document.getElementById('root'))

初始化完成后,接下来就需要考虑在组件结构中如何使用state:

  • 获取状态:this.state
    render() {
             return {
            <div> 计数器 { this.state }</div>
          }
       }

2. setState() 修改状态 

  • 状态是可变的。
  • 语法: this.setState({  需要修改的数据 })
  • 注意:不要直接修改state的值!
    class App extends React.Component {
       state = {
         count : 0
       }
       render() {
            return {
            <div> 计数器 { this.state.count }</div>
            <button onClick={() => {
                    // 正确
                    this.setState({
                         count: this.state.count + 1 
                   })
                    
                    // 错误
                    this.state.count +1 
              }}>+1</button>
          }
       }
    }
    
    ReactDOM.render(<App />,document.getElementById('root'))
  • setState() 作用:1. 修改state ; 2. 更新UI
  • 思想:数据驱动视图

3. 从 JSX 中抽离事件处理程序

  • JSX 中掺杂过多的JS逻辑程序代码,会使代码显得非常混乱。
  • 推荐:将逻辑抽离到单独的方法中,保证JSX结构清晰。
class App extends React.Component {
   state = {
     count : 0
   }

   // 事件处理程序
   OnIncreaseNumb() {
       this.setState({
          count: this.state.count + 1 
    })
}
   render() {
        return {
        <div> 计数器 { this.state.count }</div>
        <button onClick={this.OnIncreaseNumb}>+1</button>
      }
   }
}

ReactDOM.render(<App />,document.getElementById('root'))

此时,会发现页面报错:

class App extends React.Component {
   state = {
     count : 0
   }

   OnIncreaseNumb() {
       this.setState({
          count: this.state.count + 1 
    })
}
   render() {
        return {
        <div> 计数器 { this.state.count }</div>
        <button onClick={this.OnIncreaseNumb}>+1</button>
      }
   }
}

ReactDOM.render(<App />,document.getElementById('root'))

原因:事件处理程序中 this 的值为 undefined 。

解决方案:this指向组件实例(render方法中的this即是组件实例)

4. 事件绑定 this 指向

根据上述提出的问题以及解决方案,事件绑定this指向有以下三种方式:

4.1. 箭头函数

  • 利用箭头函数自身不绑定 this 的特点。
  • render() 方法中的this 为组件实例,可以获取到 setState() 。
class App extends React.Component {
   state = {
     count : 0
   }

   OnIncreaseNumb() {
       this.setState({
          count: this.state.count + 1 
    })
}
   render() {
        return {
        <div> 计数器 { this.state.count }</div>
         // 箭头函数中 this 指向外部环境 此处为:render方法
        <button onClick={ () => this.OnIncreaseNumb()}>+1</button>
      }
   }
}

ReactDOM.render(<App />,document.getElementById('root'))

4.2. Function.prototype.bind()

  • 利用ES5 中 bind() 方法,将事件处理程序中的 this与组件实例绑定在一起。
class App extends React.Component {
   constructor() {
    state = {
        count : 0
   }
    super() 
    this.OnIncreaseNumb = this.OnIncreaseNumb.bind(this)
}
   OnIncreaseNumb() {
       this.setState({
          count: this.state.count + 1 
    })
}
   render() {
        return {
        <div> 计数器 { this.state.count }</div>
        <button onClick={ this.OnIncreaseNumb }>+1</button>
      }
   }
}

ReactDOM.render(<App />,document.getElementById('root'))

4.3. class 的实例方法

  • 利用箭头函数形式的class 实例方法。
  • 注意:该语法是实验性语法,但是由于 babel 的存在可以直接使用。
class App extends React.Component {
   state = {
     count : 0
   }

   OnIncreaseNumb = () => {
       this.setState({
          count: this.state.count + 1 
    })
}
   render() {
        return {
        <div> 计数器 { this.state.count }</div>
        <button onClick={ this.OnIncreaseNumb }>+1</button>
      }
   }
}

ReactDOM.render(<App />,document.getElementById('root'))

五、表单处理

1. 受控组件

1.1 概念

  • HTML 中的表单元素是可以输入的,也就是有自己的可变状态。
  • React 中可变状态通常保存在 state 中,并且只能通过 setState() 方法来修改。
  • React 将 state 与表单元素值 value 绑定在一起,由 state 的值来控制表单元素的值

<input type="text" value={this.state.txt} />

所以,受控组件其实就是:其值受到React 控制的表单元素。

1.2 实现步骤

  1. 在state 中添加一个状态,作为表单元素的value值(控制表单元素的来源)
  2. 给表单元素绑定 onChange事件,将表单元素的值 设置为 state的值(控制表单元素值的变化)
class App extends React.Component {
   state = {
     txt: ''
   }

   handleChange = e => {
       this.setState({
          txt: e.target.value
    })
}
   render() {
        return {
        <div>  
            <input type="text" value={this.state.txt}  onChange={this.handleChange} />
        </div>
      }
   }
}

ReactDOM.render(<App />,document.getElementById('root'))

1.3  多表单元素优化

  • 问题:每个表单元素都有一个单独的事件处理程序就使得代码变得过于繁琐。
  • 优化:使用一个时间处理程序同时处理多个表单元素。

优化步骤:

  1. 给表单元素添加 name属性,名称与state 相同。
  2. 根据表单元素类型获取对应值。
  3. 在 onChange事件处理程序中通过 { name } 来修改对应的 state。
class App extends React.Component {
   state = {
     txt: '',
     content: '',
     city: 'sd',
     isChecked: false
   }

   handleChange = e => {
       // 获取当前DOM对象
       const target = e.target

       // 根据类型获取对应值
       const value = target.type === 'ckeckbox'
            ? target.checked
            : target.value

       // 根据name 设置对应state
       const name = target.name
       this.setState({
          [name]: value
    })
}
   render() {
        return {
        <div>  
            <input type="text" name="txt" value={this.state.txt}  onChange={this.handleChange} />
             <textarea name="content" value={this.state.content} onChange={this.handleContent}></textarea>
             <select name="city" value={this.state.city} onChange={this.handleCity}>
                   <option value="sd">山东</option>
                   <option value="hb">河北</option>
                   <option value="tj">天津</option>
             </select>
          <br/>
             <input name="checkex" type="checkbox" checked={this.state.isChecked} onChange={this.handleChecked}>
        </div>
      }
   }
}

ReactDOM.render(<App />,document.getElementById('root'))

2. 非受控组件

  • 说明:借助于ref,使用原生 DOM方式获取表单元素值。
  • ref 的作用:获取 DOM 或组件。

使用步骤:

  1. 调用 React.createRef() 方法创建一个 ref 对象。
    constructor() {
         super()
         this.txtRef = React.createRef()
    }
  2. 将创建好的 ref 对象添加到文本框中。
    <input type="txt" ref={this.txtRef} />
  3. 通过 ref 对象获取到文本框的值。
    console.log(this.txtRef.current.value)

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

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

相关文章

文心一言 VS 讯飞星火 VS chatgpt (70)-- 算法导论6.5 9题

九、请设计一个时间复杂度为 (n lgk)的算法&#xff0c;它能够将 k 个有序链表合并为一个有序链表&#xff0c;这里 n 是所有输入链表包含的总的元素个数。(提示:使用最小堆来完成 k 路归并。 文心一言&#xff1a; 要设计一个时间复杂度为 O(n log k) 的算法&#xff0c;将 …

CVE-2023-37582 Apache RocketMQ 远程代码执行漏洞

漏洞简介 Apache RocketMQ是一款低延迟、高并发、高可用、高可靠的分布式消息中间件。CVE-2023-37582 中&#xff0c;由于对 CVE-2023-33246 修复不完善&#xff0c;导致在Apache RocketMQ NameServer 存在未授权访问的情况下&#xff0c;攻击者可构造恶意请求以RocketMQ运行的…

线程池相关理论

什么是线程池 线程池是一种利用池化技术思想来实现的线程管理技术&#xff0c;主要是为了复用线程、便利地管理线程和任务、并将线程的创建和任务的执行解耦开来。我们可以创建线程池来复用已经创建的线程来降低频繁创建和销毁线程所带来的资源消耗。在JAVA中主要是使用Thread…

C高级--day2(用户相关操作 磁盘相关操作 shell脚本 修改环境变量)

#include<myhead.h>void fun(int n) {if(n>9){fun(n/10);printf("%d\t",n%10);putchar(10);return;}else{printf("%d\n",n%10);return;} } int main(int argc, const char *argv[]) {int num;printf("请输入一个整数&#xff1a;");sca…

华为OD机试真题 Java 实现【寻找最大价值的矿堆】【2023 B卷 100分】,附详细解题思路

目录 专栏导读一、题目描述二、输入描述三、输出描述四、Java算法源码五、效果展示1、输入2、输出 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#xff09;》。 刷的越多…

RISC-V基础之函数调用(一)简单的函数调用(包含实例)

高级语言支持函数&#xff08;也称为过程或子程序&#xff09;来重用通用的代码&#xff0c;以及使程序更加模块化和可读。函数可以有输入&#xff0c;称为参数&#xff0c;和输出&#xff0c;称为返回值。函数应该计算返回值&#xff0c;并且不产生其他意外的副作用。 在一个…

高性能网络框架笔记

目录 TCP粘包、分包惊群断开连接&#xff0c;TCP怎么检测的&#xff1f;大量的close wait&#xff0c;如何解 ?双方同时调用close水平触发和边沿触发的区别 TCP粘包、分包 解决&#xff1a;1.应用层协议头前面pktlen&#xff1b;2.为每一个包加上分隔符&#xff1b;(\r\n&…

element-ui - $prompt非空验证

//点击删除按钮 delStoreFun(data) { let than this; this.$prompt(删除门店请填写备注, 提示, { confirmButtonText: 确定, cancelButtonText: 取消, inputValidator: (value) > { //非空验证 if (!value) { return 输入不能为空 } }, }).then(({ value }) > { delS…

Typescript 枚举类型

枚举是用来表示一组明确的可选值列表 // enum是枚举类型的关键字 //枚举如果不设置值&#xff0c;默认从0开始 enum Direction {Up, // 0 Down, // 1 Left, // 2Right // 3} //如果给第一个值赋值为100&#xff0c;则第二、第三第四个都会在第一个的基础上1 分别是101,102…

数字孪生融合GIS系统能给物流领域提供什么解决方案?

全球贸易和电子商务的不断发展&#xff0c;让物流行业面临着越来越多的挑战。其中&#xff0c;提高运输效率、降低成本、优化供应链和增强可持续性等问题成为业界关注的焦点。在这个数字化时代&#xff0c;数字孪生和GIS系统的融合为物流行业带来了全新的解决方案。 数字孪生技…

奥威BI系统|秒分析,更适合分析大数据

根据以往的经验&#xff0c;当数据量多到一定程度就容易导致系统卡顿、崩溃。这种现象给企业级数据分析造成了极大的困扰。随着业务发展扩大和分析需求精细化&#xff0c;企业需要一套能秒分析大数据的系统。而奥威BI系统就是这样一款可以秒分析大数据的商业智能系统。 奥威BI…

swagger相关问题

swagger相关问题 swagger版本为&#xff1a; <dependency><groupId>com.github.xiaoymin</groupId><artifactId>swagger-bootstrap-ui</artifactId><version>1.9.6</version> </dependency> <dependency><groupId&…

matplotlib 设置y轴刻度标记的小数点数目+设置科学计数法标记

1 设置y轴刻度标记的小数点数目 使用FormatStrFormatter&#xff0c;通过使用格式字符串%1.2f来设置坐标轴刻度标签保留两位小数。 %1.2f格式字符串指定刻度标签以浮点数形式显示&#xff0c;并保留两位小数。 import matplotlib.pyplot as plt from matplotlib.ticker impo…

FeignClient接口的几种方式总结

FeignClient这个注解&#xff0c;已经封装了远程调用协议。在springboot的开发&#xff0c;或者微服务的开发过程中&#xff0c;我们需要跨服务调用&#xff0c;或者调用外部的接口&#xff0c;我们都可以使用FeignClient。 一、FeignClient介绍 FeignClient 注解是 Spring Cl…

vcruntime140_1.dll文件下载及安装方法,详细修复方案

最近在玩游戏跟打开ps的时候&#xff0c;电脑莫名出现上出现了一个名为vcruntime140_1.dll的错误提示。这个错误提示让我无法正常运行一些软件和游戏&#xff0c;给我的电脑使用带来了很大的困扰。第一时间我就在网上翻阅各种关于vcruntime140_1.dll错误的相关信息。终于让我们…

DC-1靶机

文章目录 信息收集漏洞发现漏洞利用 DC-1靶机地址下载 DC-1靶机说明 先把kali和靶机都设置成NAT模式 查看两台MAC地址 设置—网络适配器—高级—MAC地址 kali 00:0C:29:E1:A9:D2 dc-1 00:0C:29:C1:D6:77信息收集 1、找出DC-1 的IP地址 nmap -sP 192.168.80.1/24 -oN …

最佳安卓数据恢复软件〔TOP 7解决方案〕

Android 现在是世界上使用最广泛的移动操作系统&#xff0c;这意味着比以往任何时候都多的 Android 用户会丢失重要数据&#xff0c;例如照片、文档和短信。幸运的是&#xff0c;Android 数据恢复软件可以提供帮助&#xff0c;使普通人无需任何专业知识即可恢复看似永久删除的数…

删除注释(力扣)

删除注释 题目 给一个 C 程序&#xff0c;删除程序中的注释。这个程序source是一个数组&#xff0c;其中source[i]表示第 i 行源码。 这表示每行源码由 ‘\n’ 分隔。 在 C 中有两种注释风格&#xff0c;行内注释和块注释。 字符串// 表示行注释&#xff0c;表示//和其右侧…

【大数据之Flume】六、Flume进阶之自定义Source

&#xff08;1&#xff09;概述&#xff1a;   Source 是负责接收数据到 Flume Agent 的组件。Source 组件可以处理各种类型、各种格式的日志数据&#xff0c;包括 avro、thrift、exec、jms、spooling directory、netcat、sequence generator、syslog、http、legacy。但是有时…

Linux 快速创建桌面图标

在安装 tar.gz 这类型压缩文件时&#xff0c;通常启动文件是.sh文件。文章主要记录快速添加到桌面图标。 1、解压 tar -zxvf XXX.tar.gz 2、创建桌面图标文件 touch XXX.desktop 3、文件中配置 [Desktop Entry] NameXXX CommentZZZ Exec/软件可执行文件所在目录/可执行文…