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

news/2024/11/20 0:48:25/

📘前言

🚩🚩🚩
💎个人主页: 阿选不出来
💨💨💨
💎个人简介: 一名大二在校生,学习方向前端,不定时更新自己学习道路上的一些笔记.
💨💨💨
💎目前开发的专栏: JS 🍭Vue🍭
💨💨💨

文章目录

    • 📘前言
    • 一、React介绍
    • 二、create-react-app
      • 搭建本地开发环境
      • 编写一个程序
      • JSX语法
    • 三、组件的创建
      • 1.Class组件
      • 2.函数式组件
      • 3.组件的嵌套
      • 4.组件的样式
    • 四、事件绑定
        • 面试题

一、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将界面分成了各个独立的小块,每一个块就是组件,这些组件之间可以组合、嵌套,就成了我们的页面。
  3. React的特性

    1. 声明式设计-React采用声明范式,可以轻松描述应用。
    2. 高效-React通过对DOM的模拟(虚拟dom),最大限度地减少与DOM的交互。
    3. 灵活-React可以与已知的库或框架很好的配合。
    4. JSX-JSX是JavaScript语法的扩展。
    5. 组件-通过React构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
    6. 单向响应的数据流-React实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。
  4. 虚拟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"/>

四、事件绑定

事件绑定的四种方法:

首先定义一个变量: 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.stopPropagation event.preventDefault这种常用的方法。


http://www.ppmy.cn/news/18812.html

相关文章

LeetCode_单周赛_329

2544. 交替数字和 代码1 转成字符串&#xff0c;逐个判断 class Solution {public int alternateDigitSum(int n) {char[] s ("" n).toCharArray();int t 1;int ans 0;for (int i 0; i < s.length; i) {ans (s[i] - 0) * t;t -t;}return ans;} }代码2 一…

react用高阶组件优化文件结构 帮助建立高阶组件应用思路

其实高阶组件是一个将组件写的更灵活的方式&#xff0c;他的应用场景在业务开发中会非常多样 这里 我们演示一种 主要还是解决问题的思想最重要 或者是 这个不叫解决问题 而是设计组件结构的思路 我们来模拟一个场景 在src下有一个 components 文件夹目录 在 components 下有…

C++编译之(1)-g++单/多文件/库的编译及C标准的发展历程

g编译入门 本文为您介绍g的编译用法&#xff1b;通过从最简单的单文件编译&#xff0c;到多文件编译&#xff0c;再到动态库、静态库的编译及使用&#xff1b; 例子都经过实际编译并运行&#xff0c;可谓全网最良心之作呐&#xff0c;放心拷贝粘贴学习&#xff01; 1、g的编译单…

【3-神经网络八股】北京大学TensorFlow2.0

课程地址&#xff1a;【北京大学】Tensorflow2.0_哔哩哔哩_bilibiliPython3.7和TensorFlow2.1六讲&#xff1a;神经网络计算&#xff1a;神经网络的计算过程&#xff0c;搭建第一个神经网络模型神经网络优化&#xff1a;神经网络的优化方法&#xff0c;掌握学习率、激活函数、损…

【C++】从0到1入门C++编程学习笔记 - 核心编程篇:类和对象(上)

文章目录一、封装1.1 封装的意义1.2 struct和class区别1.3 成员属性设置为私有二、对象的初始化和清理2.1 构造函数和析构函数2.2 构造函数的分类及调用2.3 拷贝构造函数调用时机2.4 构造函数调用规则2.5 深拷贝与浅拷贝2.6 初始化列表2.7 类对象作为类成员2.8 静态成员三、C对…

深入理解Mysql底层数据结构

一. 索引的本质 索引是帮助MySQL高效获取数据的排好序的数据结构。 二. 索引的数据结构 二叉树红黑树Hash表BTreeBTree mysql的索引采用的是B树的结构 mysql为什么不用二叉树&#xff0c;因为对于单边增长的数据列&#xff0c;二叉树和全表扫描差不多&#xff0c;效率没有什…

国科大-高性能计算考试

考试比较难,课程比较繁琐. 高性能计算2022加粗样式考试 1. 启动MPI程序时系统生成的是1维程序 写出一个子程序或函数生成行和列通讯子 思路&#xff1a; 首先进行参数合法性的检查&#xff0c;然后将通信子对应的进程组进行划分&#xff0c;再将通信子对应的进程组进行列划分&…

grant之后要跟着flush privileges吗?

在 MySQL 里面,grant 语句是用来给用户赋权的。不知道你有没有见过一些操作文档里面提到,grant 之后要马上跟着执行一个 flush privileges 命令,才能使赋权语句生效。我最开始使用 MySQL 的时候,就是照着一个操作文档的说明按照这个顺序操作的。 那么,grant 之后真的需要…