记录一下这个特殊的日子,2020年下半年开始接触React。
这学期开学,老师让我做出点东西给他看,因为只一味地看书是完全不会有进步的,没有自己敲代码出点错误是不会得到进步的。
(优秀的程序猿都是在不断debug中得到成长的,所谓代码一年debug10年就是这样的吧)。
在和老师的一次次交流下,程序一步步变得规范,代码量一步步减少,各种各样的bug也出了,不过最后在秃头日常中,还是对付了过来。
也确实有了很大的收获提升了对React的兴趣,将这段经历分享给是小白的你,咱们共同进步,大佬请自动忽略一个菜鸟的自白,谢谢~。
不摆龙门阵了,接下来进入正题吧。
最终效果展示如下:
可实现删除、添加和完成的基本功能,同时能展示网页刷新时添加事项的时间。
项目目录结构,TodoList
是父组件,TOdoListItem
是子组件,总共就分为两个组件。
TodoList
部分:
import React, { Component } from 'react';
import TodoListItem from './TodoListItem';
import { getUuid } from './getUuid.js';
import { handleNowTime } from './getTIME';
import './index.css';
const STATUS_ITEM = 0;
class TodoList extends Component {
constructor(props) {
super(props);
this.state = {
list: [{
content: "睡觉",
status: STATUS_ITEM,
startTime: handleNowTime(new Date()),
uuid: getUuid()
},
{
content: "做作业",
status: STATUS_ITEM,
startTime: handleNowTime(new Date()),
uuid: getUuid()
}, {
content: "学习",
status: STATUS_ITEM,
startTime: handleNowTime(new Date()),
uuid: getUuid()
}, {
content: "基于B/S开发的一站式班级管理系统和代码评测系统",
status: 0,
startTime: handleNowTime(new Date()),
uuid: getUuid()
}
],
finished: 0,
inputValue: ''
};
}
handleChangeValue = (event) => {
const { value } = event.target;
this.setState({
inputValue: value
});
}
handleAddTask = () => {
const { inputValue } = this.state;
if (!inputValue) {
alert("输入为空,请重新输入待办事项");
return;
}
let nowTime = new Date();
const startTime = handleNowTime(nowTime);
let Uuid = getUuid();
var obj = {
content: inputValue,
status: STATUS_ITEM,
startTime: startTime,
uuid: Uuid
};
const { list } = this.state;
list.push(obj);
this.setState({
list,
inputValue: ''
});
}
// 更新已完成的事项
updateFinished = () => {
const { list } = this.state;
let finishedTask = 0;
list.forEach((item) => {
if (item.status === !STATUS_ITEM) {
++finishedTask;
}
});
this.setState({
finished: finishedTask
});
}
handleClickDelete = (Uuid) => {
const { list } = this.state;
const List = list.filter(item =>
item.uuid !== Uuid);
this.setState({
list: List
});
}
enterPress = (event) => {
if (event.key === 'Enter') {
this.handleAddTask();
event.target.value = ''
}
}
render() {
const { list } = this.state;
const { finished } = this.state;
const { inputValue } = this.state;
return (
<div className="container">
<h1>TO DO LIST</h1>
<hr></hr>
<div className="listItem">
<TodoListItem
list={list}
handleClickDelete={this.handleClickDelete}
updateFinished={this.updateFinished}
/>
<div className="item-count">
{finished}
已完成任务/
{list.length}
任务总数
</div>
<div className="addItem">
<input
className="add-input"
type="text"
placeholder="Add your item……"
onKeyPress={this.enterPress}
value={inputValue}
onChange={this.handleChangeValue}
/>
<button className="addButton"
onClick={this.handleAddTask}
>
添加
</button>
</div>
</div>
</div>
);
}
}
export default TodoList;
TodoListItem
部分:
import React, { Component } from 'react';
const STATUS_ITEM = 0;
class TodoListItem extends Component {
constructor(props) {
super(props);
this.state = {}
}
updateFinished() {
this.props.updateFinished();
}
// 删除任务
handleClickDelete(Uuid) {
this.props.handleClickDelete(Uuid);
}
// 点击完成事件
handleClickFinished = (Uuid) => {
const obj = [];
const { list } = this.props;
list.forEach((item) => {
if (item.uuid === Uuid) {
if (item.status === STATUS_ITEM) {
item.status = !STATUS_ITEM;
} else {
item.status = STATUS_ITEM;
}
this.updateFinished();
this.setState({
list: obj
});
}
else {
obj.push(item);
}
})
}
listMapItem = (item) => {
return (
<div className="warpper"
key={item.uuid}
>
<div className="item">
<input type="checkbox"
defaultChecked={item.status}
onClick={this.handleClickFinished.bind(this, item.uuid)}
/>
<span
style={{ textDecorationLine: item.status === STATUS_ITEM ? 'none' : 'line-through' }}
>{item.content}
</span>
</div>
<div className="startTime">
{item.startTime}
</div>
<button
className="delete-button "
onClick={this.handleClickDelete.bind(this, item.uuid)}
>
删除
</button>
</div>
);
}
listMap = () => {
const { list = [] } = this.props;
return (
list.map(item => {
return (this.listMapItem(item))
})
)
}
render() {
return (
<div>
{this.listMap()}
</div>
);
}
}
export default TodoListItem;
开发日志:
- 利用
flex
布局,尽量少用px
单位 - 改变函数命名模式,使用驼峰命名标准
- 理清数据流的转态,画图来分析
- 让代码尽量简洁
- 尽可能使用箭头函数(需要传参除外,这又是好大一个bug,后来改了)
- 父子组件里的东西不能乱写
- 让
render
里面的东西更简洁一点,这样利于以后的维护和修改,我的render
如此简单
render() { return ( <div> {this.listMap()} </div> ); }
- 公共函数应该写在组件外,而不是组件内,增加代码的可移植性和可复用性,减少删改的次数
- 使用枚举来表示事项状态,不然以后自己都不知道
status=0
表示什么意思(枚举类型应该使用大写)const STATUS_ITEM = 0;
差不多这些,接下来干DvaJs
去了,才有提升……
未完待续……