简介
React是Facebook在2013年推出的 用于构建用户界面的js框架
原生前端开发存在的问题
-
在传统的开发模式中,我们过多的去操作界面的细节,也就是使用DOM API或JQuery去操作界面中的元素
- DOM操作会存在兼容性问题,而过多的兼容性代码比较冗余
- DOM操作和页面逻辑混合在一起,不利于维护和开发,容易产生bug
-
数据(状态),往往会分散到各个地方,不方便管理和维护
React提出了以下思想:
-
以组件的方式去划分一个个功能模块
-
组件内以jsx来描述UI的样子,以state来存储组件内的状态 — ui的渲染是依赖于状态的
-
当应用的状态发生改变时,通过setState来修改状态,setState会通知React需要重新渲染界面,UI会自动发生更新
我们不需要去操作DOM
特点
声明式编程
- 我们预先按照对应的规则声明好界面内容,状态和对应的方法
- 在编写逻辑的时候,我们只需要去维护应用状态
- react会根据状态的改变,自动去更新UI界面
- UI如何渲染是依赖于页面的状态的
- 界面是通过框架中的渲染函数来进行构建的,react中是render方法
- 当状态发生改变的时候,只要重新调用render方法,就可以自动生成我们所需要的新的UI界面
组件化开发
将一个大的应用,按照功能点划分为一个个小的组件(含有html,css,js 的可复用的自包含代码块)
随后再将拆分后的代码块按照一定的方式进行整合,形成我们最后所需要编写的应用
多平台适配
在编译的时候,将代码编译为VNODE
根据不同的平台比编译成对应的内容
如果是WEB 就是DOM
如果是移动端APP 就是原生控件
Hello World
原生开发
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>命令式编程</title>
</head>
<body>
<h2 id="title"></h2>
<button id="btn">改变文本</button>
<script>
// 这种一步步的操作都是需要自己显示指定的编程方式叫做 命令式编程
const h2El = document.getElementById('title')
const btnEl = document.getElementById('btn')
h2El.innerHTML = 'Hello Wolrd'
btnEl.addEventListener('click', () => {
h2El.innerHTML = 'Hello React'
})
</script>
</body>
</html>
复制代码
React实现
「React依赖」
<!--
1. react和react-native所共同拥有的核心代码
2. 全局挂载了React]
3. 生成对应的VNODE
-->
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<!--
1. 根据不同的平台将VNODE渲染为不同的组件
1.1 如果是web端 vnode -> DOM
1.2 如果是react-native vnode -> 原生控件
2. 所以这个库的引入必须在react.js的后边
3. 全局挂载了ReactDOM对象
-->
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<!--
1. babel是前端使用非常广泛的编辑器、转换工具
2. babel的核心功能有2个:
2.1 ES6 -> ES5
(浏览器兼容性不好,但是书写方便的ES6转换为浏览器可以直接识别的,兼容性良好的ES5)
2.2 JSX -> React.createElement()
(JSX是React提供的语法糖,react无法直接识别,所以需要使用babel转换为react可以识别的React.createElement())
3. 所以在这里babel并不是必须的
-->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
复制代码
「Hello World」
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World</title>
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<!--
挂载点:
1. 所有编译后的react内容都会添加到这个dom元素下边
2. 如果挂载点下原本有内容, 会被react清空,并挂载编译后对应的内容
-->
<div id="app"></div>
<!-- 为script设置type为text/babel,表示这段js代码在加载到浏览器之前需要先经过babel的转义 -->
<script type="text/babel">
// 这是JSX语法,是React的语法糖,最后会被编译为对象,所以可以做为变量进行赋值
const msg = <h2>Hello World</h2>
// 将Vnode渲染到界面上
// 参数1: 渲染内容
// 参数2:挂载点
ReactDOM.render(msg, document.getElementById('app'))
</script>
</body>
</html>
复制代码
「数据绑定」
const content = 'Hello World'
// react中使用{}来加载变量
// {}中可以存放的是变量或合法的js表达式
const msg = <h2>{ content }</h2>
ReactDOM.render(msg, document.getElementById('app'))
复制代码
「案例实现-1 函数实现」
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World</title>
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
// 向这种我们只要声明(预先定义)好我们所需要使用的方法,数据(状态),界面等即可
// 在状态发生改变的时候,会自动去更新界面的编程方式叫做声明式编程
let msg = 'Hello World'
function handleClick() {
msg = 'Hello React'
// react是mvc框架,不是类似于vue的mvvm框架
// 所以react无法检测到状态的改变而自动去更新界面
// 所以当数据发生改变的时候,我们需要显示的取重新调用render方法,以生成对应新的界面进行渲染
render()
}
function render() {
ReactDOM.render(
<div>
{/* 在这里边可以写jsx的注释 */}
{/* JSX有且只能有一个根元素 */}
<h2>{msg}</h2>
{/* 这里的click方法是驼峰法,是react对原生的dom事件继续了二次封装 */}
<button onClick={handleClick}>改变文本</button>
</div>
, document.getElementById('app'))
}
// 界面初始化渲染
render()
</script>
</body>
</html>
复制代码
「案例实现2 — 组件化实现」
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World</title>
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
// 在react中的类组件,组件名的首字母一般大写
// 在react中的类组件需要满足以下2个条件
// 1. 继承自React.Component
// 2. 实现render方法,以返回jsx对象
class App extends React.Component {
constructor() {
// ES6中,如果使用了继承,必须在构造器中第一行调用super方法
// 以初始化父类,以便于子类可以继承父类的属性和方法
super()
// 如果需要状态发生改变的时候,可以通知react去更新界面
// 就需要将数据写在state对象中,以便于react使用setState方法进行更新
// 这是react比较特殊的地方,所以在react中数据又被称之为状态
this.state = {
msg: 'Hello World'
}
}
handleClick() {
// 在react中,如果需要数据发送改变以后,及时更新界面
// 需要调用setState方法来在修改状态后及时通知react去更新界面
this.setState({
msg: 'Hello React'
})
}
// 返回一段JSX,也就是界面内容
render() {
// 为了表示后边换行的内容是一个整体,方便阅读
// 一帮将返回的jsx使用括号进行包裹
return (
<div>
<h2>{this.state.msg}</h2>
<button onClick={() => { this.handleClick() }}>改变文本</button>
</div>
)
}
}
// App组件最后会被渲染为ReactRenderObject对象
// 也就是所有的组件最后都会被转换为js对象
ReactDOM.render(<App />, document.getElementById('app'))
</script>
</body>
</html>
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END