# React入门
# 运用React实现TodoList功能
# 创建React应用
首先安装 Node >= 8.10 和 npm >= 5.6
npx create-react-app my-app //创建名称为my-app的应用
cd my-app
npm start
1
2
3
2
3
# 实战代码——编写TodoList列表项组件
# index.js是入口
//index.js是入口
//引入React帮助理解React的语法,eg:以大写字母开头的都是组件、标签语法等等
import React from 'react';
//把组件渲染到DOM节点上
import ReactDOM from 'react-dom';
//App是最外层的组件,在React中以大写字母开头的都是组件
//import App from './App';
//引入TodoList组件(在同级目录下创建TodoList.js)
import TodoList from './TodoList';
//引入css
import './style.css';
//把App组件渲染到id为root的标签中
//ReactDOM.render(<App />, document.getElementById('root'));
//TodoList列表
ReactDOM.render(<TodoList />, document.getElementById('root'));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 编写父组件TodoList
import React , { Component , Fragment } from 'react';
//引入子组件TodoItem(在同级目录下创建TodoItem.js)
import TodoItem from './TodoItem';
/*定义一个叫做TodoList的React组件,
只要组件继承Component就变成了组件。
那么组件是什么呢?组件就是页面中的一部分。
*/
class TodoList extends Component{
/*ES6语法:当TodoList刚被创建的时候,constructor会自动执行*/
constructor(props){
super(props);
//创建了数据项并存储
this.state = {
//初始化list
list:[
'learn react1',
'learn react2'
],
//定义inputValue
inputValue: ''
}
//bind(this)让函数的this指向TodoList组件
this.handleInputChange = this.handleInputChange.bind(this);
this.handleButtonClick = this.handleButtonClick.bind(this);
this.handleDelete = this.handleDelete.bind(this);
}
//按钮点击事件
handleButtonClick(){
//调用setState改变数组
this.setState({
list: [...this.state.list,this.state.inputValue],//...是ES6语法,把之前的内容放在里面,同时也增加了内容
inputValue: ''//点击后清空inputValue,输入框DOM节点又引用了这个值
})
}
//输入框输入事件
handleInputChange(e){
this.setState({
inputValue: e.target.value//修改inputValue变为输入框输入的值(input DOM节点的值)
})
}
//列表项的删除,React的思想不让操作DOM,只需要操作数据即可
// handleItemClick(index){
// const list = [...this.state.list];//尽量不要直接操作原list,作一个副本进行操作,让性能和可调试性达到最优。
// list.splice(index,1);
// this.setState({
// list //ES6中键和值是一样的话,可以直接这么写
// //list: list //将新的list覆盖掉之前的list
// })
// }
//父组件与子组件通信
//父组件通过属性的形式向子组件传递参数
//然后子组件通过属性的形式(props)接收从父组件传递过来的参数
//列表项的删除
handleDelete(index){
const list = [...this.state.list];
list.splice(index,1);
this.setState({
list
})
}
//获取列表项
getTodoItems(){
return (
/*map是对数组做循环的函数*/
this.state.list.map((item,index) => {
// return <li key={index}
// onClick={this.handleItemClick.bind(this,index) /*bind(this)让函数的this指向TodoList组件*/}>
// {item}
// </li> /*循环展示时react要求每一项内容都要有key值且值唯一*/
return (
<TodoItem
deleteTodoItem={this.handleDelete}
key={index}
index={index}
content={item
/*将item值传递给TodoItem组件,
即:父组件通过属性的形式向子组件传递参数*/
} />
)
})
)
}
//render()函数负责页面要显示的内容
render(){
//return的内容就是页面内容
//这里使用的是jsx语法,可以直接使用标签显示的语法结构
return (
<Fragment>
<div>
<input
value={this.state.inputValue}
onChange={this.handleInputChange
/*输入后改变了inputValue,从而改变了该节点的值*/
}/>
<button /*style={{background: 'red',color: '#fff'}} 最外层{}代表里面是js表达式,里面的{}代表js对象*/
className='red_btn'
onClick={this.handleButtonClick}>add</button>
</div>
<span>React强调的是面向数据编程,对于DOM的操作React会自动帮你处理</span>
<ul>{this.getTodoItems()}</ul>
</Fragment>
);
}
}
/*定义完组件后导出,然后其他文件中才可以导入,导出和导入是配对使用的*/
export default TodoList;
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
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
# 编写子组件TodoItem
import React , {Component} from 'react';
//列表项的子组件
class TodoItem extends Component{
constructor(props){
super(props);
this.handleDelete = this.handleDelete.bind(this);
}
//子组件如果想和父组件进行通信,子组件要调用父组件传递过来的方法
//通过deleteTodoItem属性传递过来handleDelete方法,
//然后子组件调用了父组件的handleDelete并传递了索引值index
handleDelete(){
const { deleteTodoItem,index } = this.props;//ES6解构
deleteTodoItem(index);
// this.props.deleteTodoItem(this.props.index);
}
render(){
const { content } = this.props;//this.props.content 通过属性的形式(props)接收从父组件传递过来的参数
return (
<div
onClick={this.handleDelete} >
{content}
</div>
)
}
}
export default TodoItem;
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
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
# 编写style.css,使用css样式粗犷修饰
.red_btn{
background: red;
color: #fff;
}
1
2
3
4
2
3
4
至此,TodoList列表项组件的编写已完成。