📘前言
🚩🚩🚩
💎个人主页: 阿选不出来
💨💨💨
💎个人简介: 一名大二在校生,学习方向前端,不定时更新自己学习道路上的一些笔记.
💨💨💨
💎目前开发的专栏: JS 🍭Vue🍭
💨💨💨
文章目录
一、React介绍
-
React起源与发展
React起源于Facebook的内部项目,因为该公司对市场上所有JavaScript MVC框架都不满意,就决定自己写一套,用来架设Instagram的网站。做出来后,发现这套东西很好用,就在2013年5月开源了。
-
React与传统MVC的关系
- 轻量级的视图库!A JavaScript library for building user interfaces
- React不是一个完整的MVC框架,最多可以认为是MVC中的V(View),甚至React并不非常认可MVC开发模式,React构建页面UI的库。可以简单理解为,React将界面分成了各个独立的小块,每一个块就是组件,这些组件之间可以组合、嵌套,就成了我们的页面。
-
React的特性
- 声明式设计-React采用声明范式,可以轻松描述应用。
- 高效-React通过对DOM的模拟(虚拟dom),最大限度地减少与DOM的交互。
- 灵活-React可以与已知的库或框架很好的配合。
- JSX-JSX是JavaScript语法的扩展。
- 组件-通过React构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
- 单向响应的数据流-React实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。
-
虚拟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)}(不推荐)
handleClick2(){
console.log("click2",this.a);
}
第三种写法直接写成this.handleClick2
调用handleClick函数,该函数中this不指向App类,需要使用bind()方法改变this指向
4.直接在组件内定义一个非箭头函数的方法,在constructor里bind(this)(推荐)
handleClick3 = ()=>{
console.log("click3",this.a,)
}
面试题
react事件绑定与原生事件绑定有什么区别?
React并不会真正的绑定事件到每一个具体《》的元素上,而是采用时间代理的模式。
Event对象
和普通浏览器一样,事件handler会被自动传入一个
event
对象, 这个对象和普通的浏览器event
对象所包含的方法和属性都基本一致。不同的是React中的event
对象并不是浏览器提供的,而是它自己内部构建的。它同样具有event.stopPropagation
event.preventDefault
这种常用的方法。