# 写在前面
全球最火的前端框架,大厂都在用
# 优点
- 生态强大
- 上手简单
- 社区活跃
# v16.x
# 三大体系
- React.js
- RN
- React VR
# 搭建 React.js
# 安装脚手架
npm i -g create-react-app
1
# 使用脚手架创建项目
create-react-app react-learn // 项目的名称是react-learn
1
特别需要注意的是,Facebook 创建了 Create React App,该环境预先配置了构建 React 应用所需的一切。它将创建一个实时开发服务器,使用 Webpack 自动编译 React,JSX 和 ES6,自动前缀 CSS 文件,并使用 ESLint 来测试和警告代码中的错误。 之后就要求我们进入项目 然后跑起来项目
# 目录
|-- node_modules 放包的地方
|-- public
| |-- favicon.ico 网页标签左上角
| |-- index.html 模板文件
| |-- manifest.json 移动端的配置
|-- |
|-- src 源文件
| |-- index.js 入口文件
| |-- index.css
| |-- app.js
| |-- logo.svg
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
index.html
容错处理
<noscript>You need to enable JavaScript to run this app.</noscript>
1
PWA
相关
import * as serviceWorker from './serviceWorker';
1
# hello world
首先写一个 hello,App大写字母开头,自定义组件
import React, { Component } from 'react'; // 解构赋值
class App extends Component {
render() {
return <div>你好,洋小洋</div>;
}
}
export default App;
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# JSX
js 和 xml
<ul className="list">
<li>列表一</li>
<li>列表二</li>
</ul>
1
2
3
4
2
3
4
利用原生的话
var node1 = React.createElement('li', null, '列表一');
var node2 = React.createElement('li', null, '列表一');
1
2
2
Fragment
标签
render() {
return (
<Fragment>
<div>你好,洋小洋</div>;
</Fragment>
);
1
2
3
4
5
6
2
3
4
5
6
# 基本语法
# this 指向问题
render() {
return (
<Fragment>
<div>你好,洋小洋</div>
<div>
<input
value={this.state.initData}
onChange={this.iptChange.bind(this)} // 需要使用bind()改变this
></input>
</div>
</Fragment>
);
}
iptChange(e) {
console.log(this); // undefined
console.log(e);
// 使用setState()
this.setState({
initData: e.target.value
});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 循环数据到视图层
{
/* 循环数据 */
}
<div>
<ul>
{this.state.listArr.map((item, index) => {
return <li>{item}</li>;
})}
</ul>
</div>;
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
遇到的问题控制台
return <li key={index + item}>{item}</li>;
1
# 增加删除某个 list
delItem(index) {
console.log(index);
let list = this.state.listArr;
list.splice(index, 1);
this.setState({
listArr: list
});
}
addList() {
this.setState({
listArr: [...this.state.listArr, this.state.initData]
});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
在这里有个坑
delItem(index) {
let list = this.state.listArr; // 这里需要一个第三方的变量接收一下,官方不推荐直接操作state里边的数据
// 后续会影响到项目性能
list.splice(index, 1);
this.setState({
listArr: list
});
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 牵手踩坑
- 代码注释
{
/* 这不就是一个注释吗 */
}
{
// 这样勉强也可以吧
}
1
2
3
4
5
6
2
3
4
5
6
- className 直接在 jsx 文件中引入 css 文件
- 解析 HTML 标签
dangerouslySetInnerHTML = {{ __html:item}}
1
- label 标签 使用 htmlfor
# 插件提速
# 跟着写个小棋盘
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
function Square(props) {
return (
<button className="square" onClick={props.onClick}>
{props.value}
</button>
);
}
// 渲染了单独的按钮
// class Square extends React.Component {
// // Square 组件可以“记住”它被点击过,然后用 “X” 来填充对应的方格
// // constructor(props) {
// // super(props); // 构造函数必须以 super(props) 开头。
// // this.state = {
// // value: null
// // };
// // }
// render() {
// return (
// <button className="square" onClick={() => this.props.onClick()}>
// {this.props.value}
// </button>
// );
// }
// }
// 组件渲染了 9 个方块
class Board extends React.Component {
constructor(props) {
super(props);
this.state = {
squares: Array(9).fill(null),
xIsNext: true // 默认的第一步棋子
};
}
handleClick(i) {
// 通过使用 .slice() 方法创建了数组的一个副本,而不是直接修改现有的数组
const squares = this.state.squares.slice();
if (calculateWinner(squares) || squares[i]) {
return;
}
squares[i] = this.state.xIsNext ? 'X' : 'O';
this.setState({ squares: squares, xIsNext: !this.state.xIsNext });
}
renderSquare(i) {
return (
<Square
value={this.state.squares[i]}
onClick={() => this.handleClick(i)}
/>
); // Board--->Square
}
render() {
// const status = 'Next player: X';
// const status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
const winner = calculateWinner(this.state.squares);
let status;
if (winner) {
status = 'Winner: ' + winner;
} else {
status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
}
return (
<div>
<div className="status">{status}</div>
<div className="board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
</div>
<div className="board-row">
{this.renderSquare(3)}
{this.renderSquare(4)}
{this.renderSquare(5)}
</div>
<div className="board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
</div>
);
}
}
// Game 组件渲染了含有默认值的一个棋盘
class Game extends React.Component {
render() {
return (
<div className="game">
<div className="game-board">
<Board />
</div>
<div className="game-info">
<div>{/* status */}</div>
<ol>{/* TODO */}</ol>
</div>
</div>
);
}
}
function calculateWinner(squares) {
const lines = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
for (let i = 0; i < lines.length; i++) {
const [a, b, c] = lines[i];
if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
return squares[a];
}
}
return null;
}
// ========================================
ReactDOM.render(<Game />, 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# 读塔尼亚.拉西亚
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Hello React!</title>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
// 使用Babel所必需
// React code will go here
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
类组件中唯一需要的方法便是 render()
const heading = <h1 className="site-heading">Hello, React</h1>;
1
# 简单组件和类组件
// 简单组件
const MyComponent = ()=>{
return <div></div>
}
// 类组件
class MyComponent extends Component{
render(
return (
<div></div>
)
)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16