前言
文章涉及的内容可能不全面,但量很多,需要慢慢看。我花了很长的时间整理,用心分享心得,希望对大家有所帮助。但是难免会有打字的错误或理解的错误点,希望发现的可以邮箱告诉我ghui_master@163.com,我会及时的进行修改,只希望对你有所帮助,谢谢。
React 是什么?
React 是一个由 facebook 开源的 前端框架,核心专注于视图,目的是实现组件化开发;
- 组件化的概念
我们可以很直观的将有一个复杂的页面分割成若干个独立的组件,每个组件包含自己的 html 结构、样式和js逻辑,然后再将这些组件组合,即可完成一个复杂的页面。这样既减少了逻辑的复杂度,又实现了代码的重用;
- 组件化的优势:
- 可组合:一个组件可以和其他组件一起使用或者可以直接嵌套在另一个组件内部
- 可重用:每个组件都具有独立的功能,他可以被使用在多个场景中
- 可维护:每个小的组件仅仅包含自身的逻辑,更容易被理解和维护
配置 React 的开发环境
1.安装 react 的脚手架 create-react-app :
npm install create-react-app -g
2.使用 react 脚手架初始化一个项目:create-react-app 项目名,例如 :
create-react-app first-app
3.等待依赖安装完成,然后执行:
cd first-app
npm start
React 的组成部分
react由两部分组成:
- react.js 是 React 的核心库
- react-dom.js 是提供与 DOM 相关的功能,会在 window 下增加 ReactDOM 属性;其中常用的是 render 方法,render 可以将 react 元素或者组件插入到页面中;
vue是MVVM框架(model view viewModel)
需要我们处理的是
- model :data(defineProperty GETTER/SETTER)、computed、vuex...
- view :template、el、render...
- viewModel:vue本身实现,用来监听数据和视图的改变,从而实现双向数据绑定
REACT是MVC框架(model view controll)
看图

REACT脚手架:create-react-app
https://create-react-app.dev
全局环境安装脚手架
$ npm install -g create-react-app
基于脚手架快速构建工程化的项目
$ create-react-app xxx (如果电脑上安装了yarn,默认基于yarn安装)
不想安装在全局,可以基于npx一步到位 $ npx create-react-app xxx
脚手架创建的项目目录
|- node_modules 所有安装的模块
|- public
|- index.html SPA单页面应用中,各组件最后合并渲染完成的结果都会放入到页面的#root盒子中呈现
|- xxx.html MPA/SPA这里存放的是最后编译页面的模板
|- 我们还可能会在此放一些公共资源,把这些资源直接基于SRC/LINK的方式调入到页面模板中,而不是基于webpack最后合并在一起(不建议:但是项目中,可能存在一些木块不支持CommonJS/ES6Module规范,此时我们只能在这里直接引入使用了)
|- src 整个项目的大部分源码都写在这个目录下
|- index.js 项目的入口,webpack从这个文件开始导入打包(MPA中需要创建多入口文件)
|- api 数据处理
|- store REDUX公共状态管理的
|- assets 存储公共资源的(图片和样式)
|- utils 公共的JS模块
|- routes 路由管理的
|- components 公共的组件
|- ...
|- package.json
默认的配置清单
- 生产依赖项
- react REACT框架的核心,提供了状态、属性、组件、生命周期等
- react-dom 把JSX语法渲染成为真实的DOM,最后显示在浏览器中
- react-scripts 包含了当前工程化项目中webpack配置的东西(嫌弃把webpack放到项目目录中看上去太丑,脚手架把所有webpack的配置项和依赖都隐藏到node_modules中了,react-scripts这个REACT脚本执行命令,会通知webpack打包编译)
- scripts 当前项目可执行的脚本命令($ yarn xxx)
- $ yarn start => 开发环境下启动项目(默认会基于WEBPACK-DEV-SERVER创建一个服务,用来随时编译和渲染开发的内容)
- $ yarn build => 生产环境下,把编写内容打包编译,放到build文件目录下(服务器部署)
- $ yarn eject => 把所有隐藏在node_modules中的webpack配置项都暴露出来(方便自己根据项目需求,二次更改webpack配置)
yarn eject
- babel-preset-react-app 解析JSX语法的
如果执行yarn start/build 提示少模块,我们则少了谁就安装谁
- @babel/plugin-transform-react-jsx
- @babel/plugin-transform-react-jsx-source
- @babel/plugin-transform-react-jsx-selfcls
|- scripts
|- start.js => $ yarn start
|- build.js => $ yarn build
|- config
|- 这里存储的就是webpack的配置项
PACKAGE.JSON
"scripts": {
"startMac": "PORT=8081 node scripts/start.js",
"start": "set PORT=8081&&set HOST=127.0.0.1&&set HTTPS=true&&node scripts/start.js",
"build": "node scripts/build.js"
},
修改less的处理配置
- $ yarn add less less-loader
config/webpack.config.js
const cssRegex = /\.(css|less)$/;
{
test: cssRegex,
exclude: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap,
}, "less-loader"),
// Don't consider CSS imports dead code even if the
// containing package claims to have no side effects.
// Remove this when webpack adds a warning or an error for this.
// See https://github.com/webpack/webpack/issues/6571
sideEffects: true,
},
jsx 语法
-
jsx 语法是一种 js 和 HTML 混写的语法,将组件的结构,数据甚至样式都聚合在一起定义组件,最终经过编译形成普通的 javascript;
-
在 jsx 中,长得像 HTML 元素的就是 react 元素,React 使用 jsx 语法开发,学习 React 需要掌握 jsx 语法;
-
jsx 可以写在 js 文件中,也可以新建 .jsx 文件;但是在 js 文件中需要导入 React
import React from 'react';
// 导入 React 之后才能开始写 jsx 语法
jsx 示例
import React from 'react'
import ReactDOM from 'react-dom'
let data = {
name: '帅哥',
age: 18
};
let h = <h1 id="xyz">姓名:{ data.name }, 年龄:{ data.age }</h1>; // 这个 h 就是一个 react 元素,也可以成jsx元素,这个元素是虚拟DOM(js对象)
// 把 react 元素渲染到页面中
ReactDOM.render(h, document.querySelector('#root'), () => {
console.log('100');
console.log(document.getElementById('xyz'))
});
使用 jsx 的注意事项
-
JSX 元素需要放到 ReactDOM.render() 函数中,且最外层只能有一个根节点;
-
需要注意 jsx 是js,写 jsx 需注意遵守 js 的语法;
-
jsx 元素可以通过 { } 来使用表达式,注意只能是表达式,不允许写语句
-
jsx 元素同样可以使用行内属性,但是 原来 html 行内的 class 属性,在 jsx 中有特殊意义,需要改成 className ;原有的 label 的 for 属性,需要改成 htmlFor ; style属性要写成对象的形式
-
jsx 元素(react元素)并不是真正的 DOM,而是虚拟 DOM ,最终经过 babel 编译成普通js的对象;
示例:
let d1 = <div className="x1">这是一个div { false ? 1 : 0 }</div>
let d2 = (<div className={ false ? 'x1' : 'y1' }>
这是一个div
<p>这里面减值可以写一个html</p>
</div>); // 如果换行用小括号包裹起来
let d3 = <div style={{color: 'red', background: '#000'}}>11111<label htmlFor="name"><input type="text" defaultValue={data.name} id="name" /></label></div>;
ReactDOM.render(d3, document.getElementById('root'));
ReactDOM.render() 渲染
- 在执行 render 时,先将jsx虚拟的 DOM 元素转换成真实的 DOM 元素
- 并且把当前真实的 DOM 插入到真实的DOM元素中
- 把DOM 渲染到真实的 DOM 之后,才会执行后面的回调函数,可以在这个函数中操作 DOM;
在 React 中使用样式
在 react 中使用样式,直接在 js 中通过 import 导入 css 样式;最终打包的时候,webpack 会帮我们把样式处理好;
示例
import React from 'react'
import ReactDOM from 'react-dom'
import './css/3-css.css' // 在 react 中使用样式,直接在 js 中通过 import 导入 css 样式
let p1 = <p className="p1">这是一个p标签</p>; // 注意不能使用 class 指定元素类名,而应该使用 className 属性
ReactDOM.render(p1, document.querySelector('#root'));
列表渲染和条件渲染
列表渲染
React 和 Vue 类似都是数据驱动的,都可以根据给定的数据生成一组 DOM 元素,或者根据数据的特定情况生成或者不生成 DOM 元素;在 Vue 中使用 v-for 指令,但是 React 没有指令系统,需要使用 数组的 map 方法,在 map方法的回调函数中返回要生成的 jsx 元素;
示例
import React from 'react'
import ReactDOM from 'react-dom'
let ary = [
{
name: '瘦大大',
age: 18,
title: '宇宙集团军总司令'
},
{
name: '胖小小',
age: 17,
title: '银河小魔仙'
}
];
// 在 Vue 中使用 v-for,但是 React 中没有指令
// 在 React 中使用列表渲染,需要使用 数组的 map 方法,在 map 方法的回调函数中返回要生成多个的元素;
// 使用传统的匿名函数:
let lis = ary.map(function (item, index) {
return <li key={index}>姓名:{item.name};年龄:{item.age};职务:{item.title}</li>
}); // map 方法将原数组映射成一个新数组,
console.log(lis); // 虚拟 DOM 数组
let ul = (<ul>
{lis} {/*使用列表渲染出来的数据,在 html 里面使用需要使用 { lis }*/}
</ul>);
// 使用 箭头函数
let ul2 = (<ol>
{
ary.map((item, index) => <li key={index}>name: {item.name}; age: {item.age}; title: {item.title}</li>)
}
</ol>);
ReactDOM.render(ul2, document.querySelector('#root'));
条件渲染
React 同样没有 v-if,但是需要条件渲染,就需要使用 if-else 等判断语句
示例
let flag = Math.round(Math.random() * 10)
let el;
if (flag > 5) {
el = <h1>大于5</h1>
} else {
el = <h1> 小于等于 5</h1>
}
React.createElement
React.createElement() 方法是用来创建虚拟 DOM 的方法,而 jsx 语法中,jsx 元素就是 createElement 方法的语法糖;
React.createElement(type, props, ...children) 参数
- type: 标签类型
- props: 行内属性,对象数据类型
- children: 从第三个参数开始都是 type 的子元素
示例
import React from 'react';
import ReactDOM from 'react-dom';
let ele = (<h1 x="1" y="2">
hello
<span s="1">1</span>
<span>2</span>
</h1>);
let eleByCreateElement = React.createElement(
'h1',
{x: 1, y: 2},
'hello',
React.createElement('span', {s: 1}, 1),
React.createElement('span', null, 2)
);
// React.createElement(type, props, ...children)
// type: 标签类型
// props: 行内属性,对象数据类型
// children: 从第三个参数开始都是 type 的子元素
ReactDOM.render(eleByCreateElement, document.getElementById('root'));` javascript