【React】组件的创建与事件绑定

简介: 【React】组件的创建与事件绑定

一、React介绍

  1. React起源与发展
    React起源于Facebook的内部项目,因为该公司对市场上所有JavaScript MVC框架都不满意,就决定自己写一套,用来架设Instagram的网站。做出来后,发现这套东西很好用,就在2013年5月开源了。
  2. React与传统MVC的关系
  1. 轻量级的视图库!A JavaScript library for building user interfaces
  2. React不是一个完整的MVC框架,最多可以认为是MVC中的V(View),甚至React并不非常认可MVC开发模式,React构建页面UI的库。可以简单理解为,React将界面分成了各个独立的小块,每一个块就是组件,这些组件之间可以组合、嵌套,就成了我们的页面。
  1. React的特性
  1. 声明式设计-React采用声明范式,可以轻松描述应用。
  2. 高效-React通过对DOM的模拟(虚拟dom),最大限度地减少与DOM的交互。
  3. 灵活-React可以与已知的库或框架很好的配合。
  4. JSX-JSX是JavaScript语法的扩展。
  5. 组件-通过React构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
  6. 单向响应的数据流-React实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。
  1. 虚拟DOM
    DOM操作非常昂贵。我们都知道在前端开发中,性能消耗最大的就是DOM操作,而且这部分代码会让整体项目的代码变得难以维护。React把真实DOM树转换成JavaScript对象树,也就是VirtualDOM。

二、create-react-app

搭建本地开发环境

首先确保你安装了较新版本的Node.js

1、全局安装create-react-app

$ npm install -g create-react-app

创建一个项目

$ create-react-app your-app //注意命名方式

2、如果不想全局安装,可以直接使用npx

$ npx create-react-app myapp //也可以实现相同的效果

出现如下命令,就表示安装成功啦!

根据上图的提示,cd myapp进入目录并输入 npm start命令,即可运行项目。

编写一个程序

React17版本之前

import React from 'react' 
    import ReactDOM from 'react-dom' // ReactDOM 可以帮助我们把 React 组件渲染到页面上。
    ReactDOM.render(<div>111</div>,document.getElementById("root")) 

ReactDOM中的Render方法,功能就是把组件渲染并且构造 DOM 树,然后插入到页面上某个特定的元素上。

这种HTML代码与JavaScript代码混写的语法"在JavaScript写的标签的语法中叫"JSX"。

React18版本

import {createRoot} from 'react-dom/client'
const container = document.getElementById('root')
const root = createRoot(container)
root.render(<div>111</div>)

JSX语法

JSX 将 HTML 语法直接加入到 JavaScript 代码中, 再通过翻译器转换到纯JavaScript后由浏览器执行。在实际开发中,JSX在产品打包阶段都已经编译成了纯 JavaScript,不会带来任何副作用,反而会让代码更加直观并易于维护。

编译过程由Babel 的 JSX 编译实现。

如何用 JavaScript 对象表示一个DOM元素的结构?

看下面的DOM结构

<div class="app" id="root">
    <h1 class="title">
        欢迎进入react世界
    </h1>
    <p>
        react.js是一个帮助你构建页面UI的库
    </p>
</div>

用JavaScript对象表示:

{
  tag: 'div',
  arrrs: {className: 'app', id: 'appRoot'},
  children: [
    {
      tag:'h1',
          attrs: {className: 'title'},
          children: ['欢迎进入react世界']
    },
      {
          tag: 'p',
          attrs:null,
          children: ['React.js是一个构建页面 UI 的库']
      }
  ]
}

但是用Javascript 写起来太长了,结构看起来也不清晰,用HTML的方式写起来就方便多了。

于是React.js就把JavaScript的语法扩展了一下,让JavaScript语言能够支持这种直接在Javacript代码里面编写类似HTML标签结构的语法。这样写起来就方便多了。编译的过程会把类似HTML的JSX 的结构转换成JavaScript对象的结构。

下面代码:

import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.component{
    render() {
        return (
          React.createElement(
              "div",
              {
                    className: 'app',
                    id: 'appRoot'
                },
          React.createElement(
                  "h1",
                    {
                        className: 'title'
                    },
                    "欢迎进入react的世界"
                ),
            React.createElement(
                  "p",
                    null,
                    "React.js是一个构建页面 UI 的库"
                )
            )
        )
    }
}
ReactDOM.render(
  React.createElement(APP),
    document.getElementById('root')
)

React.createElement会构建一个JavaScript对象来描述你HTML结构的信息,包括标签名,属性,还有子元素等,语法为

React.createElement(
  type,
    [props],
    [...children]
)

所谓的JSX就是JavaScript 对象,所以使用React和JSX的时候一定要经过编译的过程。

JSX—使用react构造组件,babel进行编译 —> JavaScript对象 —> ReactDOM.render()—>DOM元素—>插入页面

三、组件的创建

1.Class组件

ES6的加入让JavaScript直接支持使用class来定义一个类,React创建组件的方式就是使用的类的继承,Es6 class 是目前官方推荐的使用方式,它使用了ES6标准语法来构建,看以下代码:

import React from "react"
import {createRoot} from 'react-dom/client'
class App extends React.Component{
    //jsx写法
    render(){
        return <div>hello react Component</div>
    }
}
const container = document.getElementById('root')
const root = createRoot(container)
root.render(<App></App>)

2.函数式组件

在react16.8版本之前,函数式组件又称无状态组件

16.8版本之后,函数式组件与class组件无差别

import React from "react"
import {createRoot} from 'react-dom/client'
function App(){
    return (
        <div>
            hello functional Component
        </div>
    )
}
const container = document.getElementById('root')
const root = createRoot(container)
root.render(<App></App>)

3.组件的嵌套

import React, { Component } from 'react'
import {createRoot} from 'react-dom/client'
class Navbar extends Component{
    render(){
        return <div>navbar</div>
    }
}
function Swiper(){
    return <div>swiper</div>
}
const Tabbar = ()=><div>Tabbar</div>
//以上三种写法都能创建组件
export default class App extends Component {
  render() {
    return (
        <div>
            <Navbar></Navbar>
            <Swiper></Swiper>
            <Tabbar></Tabbar>
        </div>
    )
  }
}
const container = document.getElementById('root')
const root = createRoot(container)
root.render(<App></App>)

4.组件的样式

{} 单花括号里面识别变量、支持运算

export default class App extends Component {
  render() {
      var myname = "Sblue"
      return (
        <div>
            {10+20}-{myname}
            {10>20?'aaa':'bbb'}
        </div>
      )
  }
}

行内样式写法

export default class App extends Component {
  render() {
      var obj = {
        background:"yellow"
      }
      return (
        <div>
            <div style={obj}>1111</div>
        </div>
      )
  }
}

引入css文件的写法

import React, { Component } from 'react'
import './css/index.css' //导入css模块, webpack的支持。
export default class App extends Component {
  render() {
      return (
        <div>
            <div className="active">22222222</div>
        </div>
      )
  }
}

类名采用 className 属性。

补充:

当我们使用label标签的for属性与input标签的id属性相匹配时,react用htmlfor来代替,因为在js中也能识别for这个关键字,避免发生冲突,用htmlfor表示label标签的for属性与js中for的关键字相区别。

<label htmlfor="username">用户名:</label>
            <input type="text" id="username"/>

四、事件绑定

1. 通过onXxx属性指定事件处理函数(注意大小写)

a.React使用的是自定义(合成)事件,而不是使用的原生DOM事件———为了更好的兼容性。

b.React中事件是通过事件委托方式处理的(委托给组件最外层的元素)———为了更高效

(2)通过event.target得到发生事件的DOM元素对象———不要过度使用ref

事件绑定的四种方法:

首先定义一个变量: a=100

1.直接在render里写行内的箭头函数

<button onClick={ ()=>{
            console.log(this.a,'处理逻辑过多时,不推荐使用')
        } }>add1</button>

2.在组件内使用箭头函数定义一个方法 (比较推荐)

<button onClick={ () => {
          this.handleClick4() //比较推荐
        }}>add4</button>
handleClick4 = ()=>{
  console.log("click4",this.a)
 }

3.直接在组件内定义一个非箭头函数的方法,然后再render里直接使用onClick={this.handleClick.bind(this)}(不推荐)

<button onClick={ this.handleClick2.bind(this) }>add2</button>
handleClick2(){
    console.log("click2",this.a);
 }

第三种写法直接写成this.handleClick2调用handleClick函数,该函数中this不指向App类,需要使用bind()方法改变this指向

4.直接在组件内定义一个非箭头函数的方法,在constructor里bind(this)(推荐)

<button onClick={this.handleClick3}>add3</button>
handleClick3 = ()=>{
    console.log("click3",this.a,)
  }

面试题

react事件绑定与原生事件绑定有什么区别?

React并不会真正的绑定事件到每一个具体《》的元素上,而是采用时间代理的模式。

Event对象

和普通浏览器一样,事件handler会被自动传入一个 event对象, 这个对象和普通的浏览器 event对象所包含的方法和属性都基本一致。不同的是React中的 event对象并不是浏览器提供的,而是它自己内部构建的。它同样具有 event.stopPropagationevent.preventDefault这种常用的方法。


相关文章
|
27天前
|
前端开发 UED 索引
React 图片灯箱组件 Image Lightbox
图片灯箱组件是一种常见的Web交互模式,用户点击缩略图后弹出全屏窗口展示大图,并提供导航功能。本文介绍了基于React框架的图片灯箱组件开发,涵盖初始化状态管理、图片加载与预加载、键盘和鼠标事件处理等常见问题及解决方案。通过`useState`和`useEffect`钩子管理状态,使用懒加载和预加载优化性能,确保流畅的用户体验。代码案例展示了组件的基本功能实现,包括打开/关闭灯箱、切换图片及键盘操作。
127 80
|
11天前
|
移动开发 前端开发 JavaScript
React 视频播放控制组件 Video Controls
本文介绍了如何使用 React 构建视频播放控制组件(Video Controls),涵盖基本概念、创建步骤和常见问题解决。首先,通过 HTML5 `&lt;video&gt;` 标签和 React 组件化思想,实现播放/暂停按钮和进度条等基础功能。接着,详细讲解了初始化项目、构建 `VideoControls` 组件及与主应用的集成方法。最后,针对视频无法播放、控制器状态不同步、进度条卡顿和音量控制失效等问题提供了具体解决方案,并介绍了全屏播放和自定义样式等进阶功能。希望这些内容能帮助你在实际项目中更好地实现和优化视频播放功能。
83 40
|
26天前
|
移动开发 前端开发 JavaScript
React 视频播放器组件:Video Player
本文介绍了如何使用 React 和 HTML5 `&lt;video&gt;` 标签构建自定义视频播放器组件。首先,通过创建基础的 React 项目和 VideoPlayer 组件,实现了基本的播放、暂停功能。接着,探讨了常见问题如视频加载失败、控制条样式不一致、性能优化不足及状态管理混乱,并提供了相应的解决方案。最后,总结了构建高效视频播放器的关键要点,帮助开发者应对实际开发中的挑战。
110 27
|
29天前
|
前端开发 JavaScript API
React 图片放大组件 Image Zoom
本文介绍如何使用React创建图片放大组件(Image Zoom),提升用户体验。组件通过鼠标悬停或点击触发放大效果,利用`useState`管理状态,CSS实现视觉效果。常见问题包括图片失真、性能下降和移动端支持,分别可通过高质量图片源、优化事件处理和添加触摸事件解决。易错点涉及状态管理混乱、样式冲突和过多事件绑定,建议使用上下文API、CSS模块及优化事件绑定逻辑。高级功能扩展如多张图片支持和自定义放大区域进一步丰富了组件的实用性。
58 25
|
25天前
|
存储 编解码 前端开发
React 视频上传组件 Video Upload
随着互联网的发展,视频内容在网站和应用中愈发重要。本文探讨如何使用React构建高效、可靠的视频上传组件,涵盖基础概念、常见问题及解决方案。通过React的虚拟DOM和组件化开发模式,实现文件选择、进度显示、格式验证等功能,并解决跨域请求、并发上传等易错点。提供完整代码案例,确保用户能顺畅上传视频。
128 92
|
30天前
|
移动开发 前端开发 JavaScript
React 图片裁剪组件 Image Cropper
本文介绍了在React中实现图片裁剪功能的方法,涵盖基础知识、常见问题及解决方案。首先,通过第三方库如`react-image-crop`或`cropperjs-react`可轻松实现图片裁剪。接着,针对性能和兼容性问题,提供了优化图片加载、处理裁剪区域响应慢、解决浏览器差异等方案。最后,通过代码案例详细解释了如何创建一个基本的图片裁剪组件,并提出了优化建议,如使用`React.memo`、添加样式支持及处理大图片预览,帮助开发者避免常见错误并提升用户体验。
116 67
|
6天前
|
移动开发 前端开发 UED
React 音频预览组件:Audio Preview
本文介绍如何使用 React 构建音频预览组件,涵盖基础实现、常见问题及解决方案。通过 HTML5 `&lt;audio&gt;` 标签和 React 状态管理,实现播放控制。解决文件路径、浏览器兼容性等问题,并优化性能,避免状态不同步和内存泄漏,提升用户体验。
54 22
|
2月前
|
前端开发 UED 开发者
React 悬浮按钮组件 FloatingActionButton
悬浮按钮(FAB)是常见的UI元素,用于提供突出的操作。本文介绍如何在React中使用Material-UI创建美观的FAB组件,涵盖基本概念、实现方法及常见问题解决。通过代码示例和优化技巧,帮助开发者提升用户体验,确保按钮位置、颜色、交互反馈等方面的表现,同时避免无障碍性和性能问题。
134 80
|
1天前
|
移动开发 前端开发 JavaScript
React 视频播放控制组件 Video Controls
本文深入探讨了如何使用React创建功能丰富的视频播放控制组件(Video Controls)。首先介绍了React与HTML5 `&lt;video&gt;` 标签的基础知识,展示了如何通过状态管理和事件处理实现自定义控件。接着分析了常见问题如视频加载失败、控件样式不一致、状态管理混乱和性能问题,并提供了相应的解决方案。最后通过完整代码案例详细解释了播放、暂停、进度条和音量控制的实现方法,帮助开发者在React中构建高质量的视频播放组件。
36 17
|
8天前
|
移动开发 前端开发 UED
React 音频播放器组件 Audio Player
本文介绍如何使用React创建功能丰富的音频播放器组件。基于HTML5 `&lt;audio&gt;` 标签,结合React的状态管理和事件处理,实现播放、暂停、进度和音量控制等功能。通过代码示例展示基本实现,并探讨常见问题如自动播放限制、进度条不更新、文件加载失败及多实例冲突的解决方案。同时,避免易错点如忽略生命周期管理、错误处理和性能优化,确保高效开发与良好用户体验。
62 23