07_React
1 相关术语
- React: 用于构建用户界面的 JavaScript 库
- node: 通过 JavaScript 语言开发 web 服务端
- npm:相当于 python 的 pip 工具,pip 用于安装 python 相关的各种工具,npm 用于 Node.JS 相关的各种工具
- jsx:JSX 是一种 JavaScript 的语法扩展,用于 react 中,既不是字符串也不是 HTML,有点像模板,形如:
1 | <div>{arr}</div> |
2 react 与只有 JS 的区别
单纯的 JS 是直接操作和构造 html。
react 是数据驱动界面,它通过虚拟的 html 生成标签。
react 的基础逻辑是数据由上向下单向流动。
虚拟的 html 有点类似于模板,html 中其中可嵌入变量和程序段。
举个例子,之前提交表单时将表单中每个元素取值转给 server,也就是从 html 中取值;使用 react 后,当按下按钮时,一般调用某个 react 函数,由函数内部通过数据构造请求,以及处理请求的结果,再进一步渲染控件,而非整个刷新整个界面。
3 基本概念
3.1 组件
组件 component 是 react 的核心概念,一般功能都通过组件实现。
组件名首字符必须大写,否则被认为是标签。
react 中有两种组件:函数组件(Functional Components) 和类组件(Class Components)。
3.1.1 函数组件
1 | import React from 'react'; |
3.1.2 类组件
继承自 Component,且至少实现 render 函数;constructor 为其构造函数,参数 props 用于接收外部传来的属性。
1 | import React, { Component } from 'react' |
3.1.3 组件状态
组件可以维护自己的数据,可将状态看作组件的属性。
具体实现,如上例中的 this.state={xxx}。
不能直接改变 state,否则无法引发界面刷新,需要使用 setState 函数:
1 | this.setState({ |
3.1.4 Bind 函数
ES5 之前,函数自动 bind,而在 ES6 之后,需要手动 bind 函数,比如:回调函数需要在构造里 bind,形如:
1 | render() { |
3.1.5 控件的 Key
key 可以帮助 React 高效识别哪些元素发生了改变,哪些元素没有发生改变。最好给每个控件指定 key,比如:
1 | render () { |
这使得每个控件得以区分,控制刷新,提升效率……
3.1.6 组件之间通讯
react 主导思想是数据只能从父控件向子控件流动,兄弟组件间不能通讯;数据只能被组件内部及其子组件使用。父子组间通讯,常使用方法。
- 通过设置属性 props 把父组件数据传给子组件
- 通过设置属性 props 把父组件句柄传给子组件,使子组件可调父组件中的方法(使用时注意 bind)
4 生命周期
5 第一个程序
5.1 新建一个项目
1 | create-react-app frontend |
5.2 写代码
5.2.1 react 简单示例
删除 src/下所有文件,并编辑 src/index.js 如下:
1 | import React from 'react' |
5.2.2 react-bootstrap 示例
1 | import React from 'react'; |
5.3 在浏览器中运行
启动浏览器看运行效果
1 | sudo npm start |
5.4 编译
1 | npm run build |
此时 build 目录下生成 index.html 及 static/js/,把它们复制到你的 flask 项目里,调用 index.html 即可看到用 react 生成的网页。
6 使用 VSCode 调试 React 应用
- 安装 Debugger for Chrome 插件
- 从 vscode 左侧调出运行与调式面板
- 设置配置 launch.js,将端口改为 3000
- 在终端输入 npm start,即可运行调试
- 此时在浏览器中可看到界面,修改界面不需要再次运行,即可在浏览器中同步看到效果
7 react+bootstrap
1 | $ sudo npm install react-bootstrap bootstrap@3.3.7 |
安装好后,就可以在 react 中直接使用了,如:
1 | import { Navbar, Jumbotron, Button } from 'react-bootstrap'; |
8 简单范例
1 | $ git clone https://github.com/lingjiawen/react_bootstrap_demo.git |
此时,可以在浏览器打开 localhost:8080,看到示例
9 编译前端代码
9.1.1 为什么编译
即使用 babel 这样的库可以在运行时编译 html,但会遇到以下问题:
- 在 js 中引入文件,如“import xxx from yyy”时,如果 yyy 是编译过的 xxx 可能找不到。
- yyy 往往是多个 js 文件的集合,无法单独使用
- 自己的 js 中可能使用了多个库,都放进项目里占空间大且乱
9.1.2 如何编译
1 | $ npm run build |
编译后在 build 目录下生成 html 和 js 文件
10 问题与解决
10.1 问题一
- 问题:npm start 时报错:code: 'MODULE_NOT_FOUND'
- 分析:这是由于 npm 和 node 版本不一致引起的
- 解决方法:升级 npm
1 | sudo n 6.3 # 降级node版本 |
10.2 问题二
- 问题:npm 升级了多个软件包后由于版本不匹配而无法工作
- 分析:冲突异致,由于 npm 安装了很多软件,导致使用 apt remove 删除 npm 后,冲突依然存在;当 npm 不能正常运行时,也无法管理被它安装的软件包。
- 解决方法:删除 npm 以及所有的缓存和相关安装包,它们的位置如下:
1 | HOME/.npm/* |
10.3 问题三
- 问题:console.log() 在哪显示
- 解决:在浏览器 F12,控制台里显示
10.4 问题四
- 问题:访问本机提供服务的端口时报错:No 'Access-Control-Allow-Origin' 跨域问题
- 分析:跨域问题
- 解决方法:在 flask 里设置一下 CORS,形如:
1 | from flask_cors import CORS |
10.5 问题五
- 问题:什么是脚手架
- 回答:一个工作,用于快速地构建开发环境
10.6 问题六
- 问题:如何一次渲染多个组件
- 回答:
1 | render() { |
10.7 问题七
- 问题:如何调试 JSX
- 回答:JSX 中可通过{}加入简单代码段
10.8 问题八
- 问题:用 create-react-app 创建的项目太大,无法保存
- 回答:去掉 node-modules 目录,只保存其它即可
10.9 问题九
- 问题: js 文件不能立即更新
- 回答: 浏览器 ->F12->网络面板 ->停用缓存
10.10 问题十
问题:不编译是否可以使用 react
回答:在网站中加入少量 react 代码时,可使用 bebel 工具,直接在 js 中使用 jsx 语法,引入以下包:
1 | <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> |
详见:在网站中添加 React
10.11 问题十一
问题:如何实现同时使用 jsx 和 import
回答:script type 只能设置一个值,用以下方法同时作为 module 和 bebal
1 | <script data-plugins="transform-es2015-modules-umd" type="text/babel"> |
11 参考
12 发现
它可以用不同的 class 描绘不同的控件
setstate 会触发渲染
控制台会打出错误信息
13 访问远程数据
1 | $ npm isntall axios --save |