React实现一个TodoList案例,大部分教学视频里面好像都会教,笔者会点JavaScript,略微学了点Vue,写起React来到也轻松,看点React对Vue的组件化到也是一种新的理解方式。
话不多说,环境搭建。
1
| npx create-react-app todolist
|
此步操作会新建一个todolist
文件夹,使用Vscode打开此文件夹,安装所需依赖
1 2 3 4
| npm install bootstrap
npm install reactstrap
|
首先删除src下所有文件,然后根据此文内容在src下一个一个新建文件即可。
新建index.js
1 2 3 4 5 6 7 8 9 10 11 12
| import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; import "bootstrap/dist/css/bootstrap.min.css";
const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <React.StrictMode> <App /> </React.StrictMode> );
|
新建App.js
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
| import "./App.css"; import React from "react"; import InputTodo from "./InputTodo"; import TodoList from "./TodoList"; import EndFoot from "./EndFoot";
const lsKey = "todoList"; const setlocalState = (state) => { localStorage.setItem(lsKey, JSON.stringify(state)); }; const getlocalState = () => { const str = localStorage.getItem(lsKey); if (str) { return JSON.parse(str); } else { return []; } };
class App extends React.Component { constructor(props) { super(props); this.state = { todoList: getlocalState(), }; } addTodoList = (item) => { const todoList = this.state.todoList.slice(); todoList.unshift(item); this.setState({ todoList: todoList }); setlocalState(this.state.todoList); }; removeTodoList = (index) => { if (window.confirm("确认删除任务?")) { const todoList = this.state.todoList.slice(); todoList.splice(index, 1); this.setState({ todoList: todoList }); setlocalState(this.state.todoList); } }; checkAll = () => { const todoList = this.state.todoList.slice(); todoList.forEach((item) => { item.check = true; }); this.setState({ todoList: todoList }); setlocalState(this.state.todoList); }; checkNoAll = () => { const todoList = this.state.todoList.slice(); todoList.forEach((item) => { item.check = false; }); this.setState({ todoList: todoList }); setlocalState(this.state.todoList); }; mouseOverOut = (index, type) => { const todoList = this.state.todoList.slice(); const item = todoList[index]; item.showDel = type; todoList.splice(index, 1, item); this.setState({ todoList: todoList }); setlocalState(this.state.todoList); };
clickItem = (index) => { const todoList = this.state.todoList.slice(); const item = todoList[index]; item.check = !item.check; todoList.splice(index, 1, item); this.setState({ todoList: todoList }); setlocalState(this.state.todoList); };
clearCheckItem = () => { const todoList = this.state.todoList.slice(); this.setState({ todoList: todoList.filter((i) => !i.check) }); setlocalState(this.state.todoList); }; render() { return ( <div className="App"> <div className="content"> <InputTodo addTodoList={this.addTodoList} /> <TodoList todoList={this.state.todoList} mouseOverOut={this.mouseOverOut} clickItem={this.clickItem} removeTodoList={this.removeTodoList} /> <EndFoot todoList={this.state.todoList} clearCheckItem={this.clearCheckItem} checkAll={this.checkAll} checkNoAll={this.checkNoAll} /> </div> </div> ); } } export default App;
|
新建App.css
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
| .App { display: flex; justify-content: center; align-items: center; }
.App .content { border: 1px solid #ccc; padding: 5px; width: 400px; } .App .list { padding-top: 5px; padding-bottom: 5px; }
.App .list .item { display: flex; height: 30px; justify-content: space-between; align-items: center; }
.App .end { height: 47px; display: flex; justify-content: space-between; align-items: center; border: solid #b6c3d0 1px; border-radius: 5px; }
|
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
| import { Input } from "reactstrap"; import React from "react";
class InputTodo extends React.Component { constructor(props) { super(props); this.state = { inputText: "", }; } render() { return ( <div> <Input value={this.state.inputText} onChange={(e) => this.setState({ inputText: e.target.value })} placeholder="请输入任务名称, 按回车键确认" onKeyDown={(event) => { if (event.key === "Enter") { if (!this.state.inputText) { alert("不可添加空任务"); return; } this.props.addTodoList({ showDel: false, check: false, label: this.state.inputText, }); this.setState({ inputText: "" }); } }} /> </div> ); } } export default InputTodo;
|
新建TodoList.js
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
| import { Input, ListGroupItem, ListGroup, Button } from "reactstrap"; import React from "react"; class TodoList extends React.Component { renderList() { return this.props.todoList.map((i, index) => { return ( <ListGroupItem key={index} action href="#" tag="a" onClick={() => this.props.clickItem(index)} onMouseOver={() => this.props.mouseOverOut(index, true)} onMouseOut={() => this.props.mouseOverOut(index, false)} > <div className="item"> <div> <Input type="checkbox" id="checkItem" checked={i.check} onChange={(e) => {}} /> <span style={{ paddingLeft: "10px" }}>{i.label}</span> </div> <div> {i.showDel ? ( <Button color="danger" size="sm" onClick={(e) => { e.stopPropagation(); this.props.removeTodoList(index); }} > 删除 </Button> ) : ( <div></div> )} </div> </div> </ListGroupItem> ); }); }
render() { return ( <div className="list"> <ListGroup>{this.renderList()}</ListGroup> </div> ); } } 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
| import { Input, Button } from "reactstrap"; import React from "react";
class EndFoot extends React.Component { render() { return ( <div className="end"> <div style={{ paddingLeft: "17px" }}> <Input type="checkbox" checked={ this.props.todoList.filter((i) => i.check).length === this.props.todoList.length } onChange={(e) => { if (e.target.checked) { this.props.checkAll(); } else { this.props.checkNoAll(); } }} /> <span style={{ paddingLeft: "10px" }}> 已完成{this.props.todoList.filter((i) => i.check).length}/全部 {this.props.todoList.length} </span> </div>
<div> {this.props.todoList.filter((i) => i.check).length > 0 ? ( <Button color="danger" size="sm" onClick={this.props.clearCheckItem} > 清除已完成任务 </Button> ) : ( <div></div> )} </div> </div> ); } } export default EndFoot;
|
最后运行项目
即可查看效果,代码不多,展示了最经典的React写法,很适合用来了解学习React。
封面