React
虚拟 DOM
- 通过 JS 模拟虚拟 DOM, 一个节点一个对象模拟, 节点之间出现了嵌套就成了一个 DOM
- 通过虚拟 DOM 实现 DOM 的高效更新(通过 Diff 算法比较新旧两个 DOM, 找出差异部分, 进行局部更新)
- Diff 算法
- tree diff: DOM 树时分层的, 每一层的比较就是 tree diff
- component diff: 在比较每一层的时候, 先比较组件的类型, 如果类型不一致就立即更新, 如果一直, 则在 component diff 算法这一层则临时认为二者相同
- element diff: 在 component diff 之后, 比较 component 中的元素
React 项目结构
.
├── build
├── package.json
├── src
│ ├── index.html
│ └── main.js
├── webpack.config.js
└── yarn.lock
2 directories, 5 files
- 和 vue.js 类似, 也是采用 Webpack 进行打包
- 需要的包
- react: 管理组件的创建和删除等于声明周期相关的操作
- react-dom: 管理虚拟 DOM, 将节点渲染到 DOM 上
React 创建元素
import React from 'react';
import ReactDOM from 'react-dom';
var div = React.createElement('div', {
title: 'This is my first div created by React',
id: 'first-div'
}, 'I am who I am');
ReactDOM.render(div, document.querySelector('#app'));
render
的第一个参数要是一个 var div 之类的 container, 不能使我们定义的组件, 这和 vue 的 template 类似
配置 JSX
yarn add -D @babel/preset-react
yarn add -D babel-preset-react
- 在 .babelrc 中添加 js 和 jsx 的正则
JSX 语法(在 JSX 语法内部)
- 在
{ }
中可以写任何 js 的代码表达式
- 在
< >
中可以写 JSX 语法
- 元素属性
class
为 className
, 因为在 es6 中 class
是关键字
- 元素属性
for
要替换为 htmlFor
- 使用注释, 需要把注释放到
{}
中, 里面使用 /**/
, 最终就是 { /* */ }
- 创建组件
- 方法一
function Foo() {}
构造函数, 注意: React 在解析标签的时候, 是按照标签的首字母大小写进行区分的, 如果为小写则 HTML 解析, 如果为大写则 React 解析
- 组件传值, 通过属性绑定传递给子组件, 在组件中如果要使用外部传递的值, 需要在构造函数中显示指定, 传递到子组件中的值都是只读的
- 方法二
- 定义一个类, 继承
React.Component
, 实现 render
方法, 需要 return
我们需要其渲染的元素
- 组件传值时, 可以直接通过
this.props.属性名
获得, 这个功能是通过继承 React.Component
实现的, 和 function 定义一样, 属性都是只读的
- 如果我们要显示定义一个
constructor
, 一定要在参数中写 props
, 再将 props
传给 super(props)
- 除了
this.props
, 还有 this.state
保存自己的数据
- 有自己的生命周期函数
- 在
render
return 是一般加上 ()
清晰一点
css 模块化
yarn add -D babel-plugin-react-css-modules
安装 css modules 插件
- 在
webpack.config.js
中的 css
匹配中, 添加如下代码
['style-loader', {
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]_[local]-[hash:base64:5]',
}
}
}]
- 所谓的 css 模块化也就是对 className 进行重命名, 使用了模块化的 css, .css 文件中默认定义的就是私有的, 如果加上
.global(.name) {font-size: 20px;}
等就不会对其进行重命名, 也就成为了全局 css
jsx 中常用
- 遍历数据
list.map((item) => {
return (
...
)
})