0%

React 学习

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的特性

image-20230107213442334

虚拟DOM

image-20230107213540016

image-20230107213547563

create-react-app

全局安装create-react-app

1
$ npm install -g create-react-app

创建一个项目

1
2
3
4
5
6
$ create-react-app your-app 注意命名方式

Creating a new React app in /dir/your-app.

Installing packages. This might take a couple of minutes. 安装过程较慢,
Installing react, react-dom, and react-scripts...

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

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

这需要等待一段时间,这个过程实际上会安装三个东西

  • react: react的顶级库
  • react-dom: 因为react有很多的运行环境,比如app端的react-native, 我们要在web上运行就使用react-dom
  • react-scripts: 包含运行和打包react应用程序的所有脚本及配置

出现下面的界面,表示创建项目成功:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Success! Created your-app at /dir/your-app
Inside that directory, you can run several commands:

npm start
Starts the development server.

npm run build
Bundles the app into static files for production.

npm test
Starts the test runner.

npm run eject
Removes this tool and copies build dependencies, configuration files and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

cd your-app npm start

Happy hacking!

根据上面的提示,通过cd your-app 命令进入目录并运行npm start 即可运行项目。生成项目的目录结构如下:

image-20230107214117497

常见问题:

  • npm安装失败
    • 切换为npm镜像为淘宝镜像
    • 使用yarn,如果本来使用yarn还要失败,还得把yarn的源切换到国内
    • 如果还没有办法解决,请删除node_modules及package-lock.json然后重新执行 npm install 命令
    • 再不能解决就删除node_modulespackage-lock.json的同时清除npm缓存npm cache clean –force 之后再执行npm install 命令

编写第一个react应用程序

react开发需要引入多个依赖文件:react.js、react-dom.js,分别又有开发版本和生产版本,create- react-app里已经帮我们把这些东西都安装好了。

把通过CRA创建的工程目录下的src目录清空,然后在 里面重新创建一个index.js. 写入以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
// 从 react 的包当中引入了 React。只要你要写 React.js 组件就必须引入React, 因为react里有一种语法叫JSX,稍后会讲到JSX,要写JSX,就必须引入React
import React from 'react'
// ReactDOM 可以帮助我们把 React 组件渲染到页面上去,没有其它的作用了。它是从 react-dom 中引入的,而不是从 react 引入。
import ReactDOM from 'react-dom'

// ReactDOM里有一个render方法,功能就是把组件渲染并且构造 DOM 树,然后插入到页面上某个特定的元素上
ReactDOM.render(
// 这里就比较奇怪了,它并不是一个字符串,看起来像是纯 HTML 代码写在 JavaScript 代码里面。语法错误吗?这并不是合法的 JavaScript 代码, “在 JavaScript 写的标签的”语法叫 JSX- JavaScript XML。
<h1>欢迎进入React的世界</h1>,
// 渲染到哪里
document.getElementById('root')
)

image-20230107214602619

JSX语法与组件

1. JSX语法

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

https://reactjs.org/docs/hello-world.html

原理是什么呢?

要明白JSX的原理,需要先明白如何用 JavaScript 对象来表现一个 DOM 元素的结构? 看下面的DOM结构

1
2
3
4
5
6
<div class='app' id='appRoot'>
<h1 class='title'>欢迎进入React的世界</h1>
<p>
React.js 是一个帮助你构建页面 UI 的库
</p>
</div>

上面这个 HTML 所有的信息我们都可以用 JavaScript 对象来表示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
tag: 'div',
attrs: { 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 语言能够支持这种直接在 JavaScript 代码里面编写类似 HTML 标签结构的语法,这样写起来就方便很多了。编译的过程会把类似 HTML 的 JSX 结构转换成 JavaScript 的对象结构。

下面代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import React from 'react'
import ReactDOM from 'react-dom'


class App extends React.Component {
render () {
return (
<div className='app' id='appRoot'>
<h1 className='title'>欢迎进入React的世界</h1>
<p>
React.js 是一个构建页面 UI 的库
</p>
</div>
)
}
}

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

编译之后将得到这样的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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 结构的信息,包括标签名、属性、还有子元素等, 语法为

1
2
3
React.createElement(type,
[props], [...children]
)

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

image-20230107215643833

2.Class组件

ES6的加入让JavaScript直接支持使用class来定义一个类,react创建组件的方式就是使用的类的继承,

ES6 class 是目前官方推荐的使用方式,它使用了ES6标准语法来构建,看以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
import React from 'react'
import ReactDOM from 'react-dom'

class App extends React.Component {
render() {
return (
<h1>欢迎进入React的世界</h1>
)
}
}
ReactDOM.render(
<App />, document.getElementById('root')
)

es6 class 组件其实就是一个构造器,每次使用组件都相当于在实例化组件,像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import React from 'react'
import ReactDOM from 'react-dom'

class App extends React.Component {
render() {
return (
<h1>欢迎进入{this.props.name}的世界</h1>
)
}
}

const app = new App({
name: 'react'
})
.render()

ReactDOM.render(app,
document.getElementById('root')
)

3. 函数式组件

1
2
3
4
5
6
7
import React from 'react'
import ReactDOM from 'react-dom'
const App = (props) => <h1>欢迎进入React的世界</h1>
ReactDOM.render(
// React组件的调用方式
<App />, document.getElementById('root')
)

这样一个完整的函数式组件就定义好了。但要注意!注意!注意!组件名必须大写,否则报错。

4. 组件的样式

  • 行内样式

    想给虚拟dom添加行内样式,需要使用表达式传入样式对象的方式来实现:

    1
    2
    // 注意这里的两个括号,第一个表示我们在要JSX里插入JS了,第二个是对象的括号
    <p style={{color:'red', fontSize:'14px'}}>Hello world</p>

    行内样式需要写入一个样式对象,而这个样式对象的位置可以放在很多地方,例如render 函数里、组件原型上、外链js文件中

  • 使用class

    React推荐我们使用行内样式,因为React觉得每一个组件都是一个独立的整体

    其实我们大多数情况下还是大量的在为元素添加类名,但是需要注意的是,class关键字需要写成className因为毕竟是在写类js代码,会收到js规则的现在,而class是关键字

    1
    <p className="hello">Hello world</p>

    注意

    class ==> className , for ==> htmlFor(label)

5. 事件处理

1. 绑定事件

采用on+事件名的方式来绑定一个事件,注意,这里和原生的事件是有区别的,原生的事件全是小写onclick , React里的事件是驼峰 onClick ,React的事件并不是原生事件,而是合成事件。

2. 事件handler的写法

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

3. Event对象

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

6. Ref的应用

1. 给标签设置ref=”username”

通过这个获取this.refs.username , ref可以获取到应用的真实dom

2. 给组件设置ref=”username”

通过这个获取this.refs.username ,ref可以获取到组件对象

3. 新的写法

1
2
3
4
5
6
myRef = React.createRef()

<div ref = {
this.myRef
} > hello < /div>
//访问this.myRef.current
-------------本文结束感谢您的阅读-------------