react-TodoList案例

 2023-09-10 阅读 18 评论 0

摘要:TodoList案例 一 TodoList案例_静态组件 需要理解的概念有: 根据目标页面进行组件拆分规划样式内容的变化className与style的变化样式文件的拆分App.css以及各个模块的xxx.css样式文件如果是全局样式,可以考虑在public里进行引入 todos的静态页面(opens new win

TodoList案例

一 TodoList案例_静态组件

需要理解的概念有:

  • 根据目标页面进行组件拆分规划
  • 样式内容的变化className与style的变化
  • 样式文件的拆分App.css以及各个模块的xxx.css样式文件
  • 如果是全局样式,可以考虑在public里进行引入

todos的静态页面(opens new window)

image-20210516153821397

image-20210516201448857

react优秀开源项目、src/App.js

import Header from './components/Header';
import Footer from './components/Footer';
import List from './components/List';
import './App.css';function App() {return (<div className='todo-container'><div className='todo-wrap'><Header /><List /><Footer /></div></div>);
}export default App;

src/App.css

/*base*/
body {background: #fff;
}.btn {display: inline-block;padding: 4px 12px;margin-bottom: 0;font-size: 14px;line-height: 20px;text-align: center;vertical-align: middle;cursor: pointer;box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);border-radius: 4px;
}.btn-danger {color: #fff;background-color: #da4f49;border: 1px solid #bd362f;
}.btn-danger:hover {color: #fff;background-color: #bd362f;
}.btn:focus {outline: none;
}.todo-container {width: 600px;margin: 0 auto;
}.todo-container .todo-wrap {padding: 10px;border: 1px solid #ddd;border-radius: 5px;
}

src/components/Header/index.js

import React, { Component } from 'react';
import './index.css';
export default class Header extends Component {render() {return (<div className='todo-header'><input type='text' placeholder='请输入你的任务名称,按回车键确认' /></div>);}
}

src/components/Header/index.css

/*header*/
.todo-header input {width: 560px;height: 28px;font-size: 14px;border: 1px solid #ccc;border-radius: 4px;padding: 4px 7px;
}.todo-header input:focus {outline: none;border-color: rgba(82, 168, 236, 0.8);box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
}

src/components/Footer/index.js

import React, { Component } from 'react';
import './index.css';
export default class Footer extends Component {render() {return (<div className='todo-footer'><label><input type='checkbox' /></label><span><span>已完成0</span> / 全部2</span><button className='btn btn-danger'>清除已完成任务</button></div>);}
}

react框架?src/components/Footer/index.css

/*footer*/
.todo-footer {height: 40px;line-height: 40px;padding-left: 6px;margin-top: 5px;
}.todo-footer label {display: inline-block;margin-right: 20px;cursor: pointer;
}.todo-footer label input {position: relative;top: -1px;vertical-align: middle;margin-right: 5px;
}.todo-footer button {float: right;margin-top: 5px;
}

src/components/List/index.js

import React, { Component } from 'react';
import Item from '../Item';
import './index.css';export default class List extends Component {render() {return (<ul className='todo-main'><Item /><Item /></ul>);}
}

src/components/List/index.css

/*main*/
.todo-main {margin-left: 0px;border: 1px solid #ddd;border-radius: 2px;padding: 0px;
}.todo-empty {height: 40px;line-height: 40px;border: 1px solid #ddd;border-radius: 2px;padding-left: 5px;margin-top: 10px;
}

src/components/Item/index.js

import React, { Component } from 'react';
import './index.css';
export default class Item extends Component {render() {return (<li><label><input type='checkbox' /><span>xxxxx</span></label><button className='btn btn-danger' style={{ display: 'none' }}>删除</button></li>);}
}

src/components/Item/index.css

/*item*/
li {list-style: none;height: 36px;line-height: 36px;padding: 0 5px;border-bottom: 1px solid #ddd;
}li label {float: left;cursor: pointer;
}li label li input {vertical-align: middle;margin-right: 6px;position: relative;top: -1px;
}li button {float: right;display: none;margin-top: 3px;
}li:before {content: initial;
}li:last-child {border-bottom: none;
}

二 TodoList案例_初始化列表

国内reactnative案例,需要理解的概念有:

  • 状态的初始化设置
  • 属性的传递与接收
  • 属性的逐一传递与批量属性传递
  • checkbox的checked设置与defaultChecked设置

src/App.js

import React, { Component } from 'react';
import Header from './components/Header';
import Footer from './components/Footer';
import List from './components/List';
import './App.css';// 统一修改成类组件
class App extends Component {// 初始化状态state = {todos: [{ id: '001', name: '吃饭', done: true },{ id: '002', name: '睡觉', done: false },{ id: '003', name: '敲代码', done: true },],};render() {// 解构赋值const { todos } = this.state;return (<div className='todo-container'><div className='todo-wrap'><Header /><List todos={todos} /><Footer /></div></div>);}
}export default App;

src/components/List/index.js

import React, { Component } from 'react';
import Item from '../Item';
import './index.css';export default class List extends Component {render() {const { todos } = this.props;return (<ul className='todo-main'>{todos.map((todo) => {
// return <Item key={todo.id} id={todo.id} name={todo.name} done={todo.done} />;
// 利用展开式参数传递进行批量属性传递return <Item key={todo.id} {...todo} />;})}</ul>);}
}

src/components/Item/index.js

import React, { Component } from 'react';
import './index.css';
export default class Item extends Component {render() {const { id, name, done } = this.props;return (<li><label>{/*checkbox设置checked会报警告信息根据建议换成defaultChecked属性*/}<input type='checkbox' defaultChecked={done} /><span>{name}</span></label><button className='btn btn-danger' style={{ display: 'none' }}>删除</button></li>);}
}

三 TodoList 案例_添加一个 todo

需要理解的概念有:

  • 将方法以属性方式传递,在子组件调用,父组件回调
  • 键盘事件,判断触发的按键
  • 唯一码的生成,安装与引入第三方模块
  • 数组对象的合并与新增
  • 清空输入框内容

reactnative案例?src/App.js

import React, { Component } from 'react';
import Header from './components/Header';
import Footer from './components/Footer';
import List from './components/List';
import './App.css';// 统一修改成类组件
class App extends Component {// 初始化状态state = {todos: [{ id: '001', name: '吃饭', done: true },{ id: '002', name: '睡觉', done: false },{ id: '003', name: '敲代码', done: true },],};render() {// 解构赋值const { todos } = this.state;return (<div className='todo-container'><div className='todo-wrap'><Header addTodo={this.addTodo} /><List todos={todos}/><Footer /></div></div>);}// addTodo用于添加一个todo,接收的参数是一个todo对象addTodo = (todoObj) => {const { todos } = this.state;// 追加一个todoconst newTodos = [todoObj, ...todos];// 更新状态this.setState({todos: newTodos,});};
}export default App;

src/components/Header/index.js

import React, { Component } from 'react';
import './index.css';
import { nanoid } from 'nanoid';export default class Header extends Component {render() {return (<div className='todo-header'><input type='text' onKeyUp={this.handleKeyUp} placeholder='请输入你的任务名称,按回车键确认' /></div>);}handleKeyUp = (e) => {// console.log(e.target.value, e.keyCode);const { keyCode, target } = e;if (keyCode !== 13) return; // 只能是按下回车键// 添加的名称不能为空if (target.value.trim() === '') {alert('输入不能为空');return;}const todoObj = { id: nanoid(), name: target.value, done: false };// 将todoObj传递给App组件中的addTodo函数this.props.addTodo(todoObj);// 清空输入target.value = '';};
}

四 TodoList 案例_勾选一个 todo

需要理解的概念有:

  • checked 与 defaultChecked 的差异与区别
  • 利用回调传递自定义参数与 event 事件参数
  • 多层组件嵌套时事件的传递与使用操作
  • 数组的遍历与数组对象的修改

src/components/Item/index.js

import React, { Component } from 'react';
import './index.css';
export default class Item extends Component {render() {const { id, name, done } = this.props;return (<li><label>{/*checkbox设置checked会报警告信息根据建议换成defaultChecked属性关于checked与defaultChecked属性的使用原则 :1.checked属性不能单独使用,时时刻刻起作用,必须配合onChanged和disabled使用,否则会有错误提示2.defaultChecked只控制初始渲染是否勾选*/}<input type='checkbox' checked={done} onChange={this.update(id)} /><span>{name}</span></label><button className='btn btn-danger' style={{ display: 'none' }}>删除</button></li>);}// 利用回调函数传递event事件// updateTodo的函数应该是最顶层的组件传递到上层组件,// 再由上层组件再传递给当前组件update = (id) => {return (e) => {this.props.updateTodo(id, e.target.checked);};};
}

Src/App.js

import React, { Component } from 'react';
import Header from './components/Header';
import Footer from './components/Footer';
import List from './components/List';
import './App.css';// 统一修改成类组件
class App extends Component {// 初始化状态state = {todos: [{ id: '001', name: '吃饭', done: true },{ id: '002', name: '睡觉', done: false },{ id: '003', name: '敲代码', done: true },],};render() {// 解构赋值const { todos } = this.state;return (<div className='todo-container'><div className='todo-wrap'><Header addTodo={this.addTodo} /><List todos={todos} updateTodo={this.updateTodo} /><Footer /></div></div>);}// addTodo用于添加一个todo,接收的参数是一个todo对象addTodo = (todoObj) => {const { todos } = this.state;// 追加一个todoconst newTodos = [todoObj, ...todos];// 更新状态this.setState({todos: newTodos,});};updateTodo = (id, done) => {console.log(id, done);// todos 从this.state进行解构赋值以后,不再是state的todosconst { todos } = this.state;// 修改todos也不是修改state里的todostodos.map((todoObj) => {if (todoObj.id === id) todoObj.done = done;return todoObj;});this.setState({ todos });};
}export default App;

react例子?src/components/List/index.js

import React, { Component } from 'react';
import Item from '../Item';
import './index.css';export default class List extends Component {render() {const { todos, updateTodo } = this.props;return (<ul className='todo-main'>{todos.map((todo) => {
// return <Item key={todo.id} id={todo.id} name={todo.name} done={todo.done} />;
// 利用展开式参数传递进行批量属性传递return <Item key={todo.id} {...todo} updateTodo={updateTodo} />;})}</ul>);}
}

五 不要直接修改 state 中的数据

需要理解的概念有:

  • 第 21 章节最后一句:状态数据,不能直接修改或更新,需要利用 setState 进行状态改新
  • 不能直接修改或者更新的意思还说的是不建议直接修改原来的 state 状态值数据
  • 对象拷贝如何实现

src/App.js

import React, { Component } from 'react';
import Header from './components/Header';
import Footer from './components/Footer';
import List from './components/List';
import './App.css';// 统一修改成类组件
class App extends Component {// 初始化状态state = {todos: [{ id: '001', name: '吃饭', done: true },{ id: '002', name: '睡觉', done: false },{ id: '003', name: '敲代码', done: true },],};render() {// 解构赋值const { todos } = this.state;return (<div className='todo-container'><div className='todo-wrap'><Header /><List todos={todos} updateTodo={this.updateTodo} /><Footer /></div></div>);}updateTodo = (id, done) => {/*// 禁止使用非setState的形式去修改state中的数据// 如下代码就是典型的违反上述原则案例console.log(id, done);// todos 从this.state进行解构赋值以后,不再是state的todosconst { todos } = this.state;// 修改todos也不是修改state里的todostodos.map((todoObj) => {if (todoObj.id === id) todoObj.done = done;return todoObj;});this.setState({ todos });*/const todos = this.state.todos;const newTodos = todos.map((todoObj) => {if (todoObj.id === id) return { ...todoObj, done };return todoObj;});console.log(todos);console.log(newTodos);this.setState({ todos: newTodos });};
}export default App;

六 TodoList案例_高亮一个todo

需要理解的概念有:

  • 属性有效性验证的尝试
  • 事件绑定时event与自定义参数传递的两种形式
  • 鼠标的移入移出事件
  • 行内样式的动态绑定方式

src/components/Header/index.js

import React, { Component } from 'react';
import './index.css';
import { nanoid } from 'nanoid';
import PropTypes from 'prop-types';
// prop-types为默认安装模块,不需要再安装export default class Header extends Component {static propTypes = {addTodo: PropTypes.func.isRequired,todos: PropTypes.array.isRequired, // 添加todos将报以错误};render() {return (<div className='todo-header'><input type='text' onKeyUp={this.handleKeyUp} placeholder='请输入你的任务名称,按回车键确认' /></div>);}handleKeyUp = (e) => {// console.log(e.target.value, e.keyCode);const { keyCode, target } = e;if (keyCode !== 13) return; // 只能是按下回车键// 添加的名称不能为空if (target.value.trim() === '') {alert('输入不能为空');return;}const todoObj = { id: nanoid(), name: target.value, done: false };// 将todoObj传递给App组件中的addTodo函数this.props.addTodo(todoObj);// 清空输入target.value = '';};
}

node react?src/components/Item/index.js

import React, { Component } from 'react';
import './index.css';export default class Item extends Component {state = {mouse: false,};render() {const { mouse } = this.state;const { id, name, done } = this.props;return (<listyle={{ backgroundColor: mouse ? '#ddd' : '#fff' }}onMouseEnter={() => this.handleMouse(true)}onMouseLeave={() => this.handleMouse(false)}><label>{/*checkbox设置checked会报警告信息根据建议换成defaultChecked属性*/}<input type='checkbox' checked={done} onChange={this.update(id)} /><span>{name}</span></label><button className='btn btn-danger' style={{ display: mouse ? 'block' : 'none' }}>删除</button></li>);}// 在事件绑定的时候利用箭头函数可以传递event与自定义参数// 不需要利用函数回调的形式传递event与自定义参数handleMouse = (flag) => {this.setState({ mouse: flag });};update = (id) => {return (e) => {this.props.updateTodo(id, e.target.checked);};};
}

七 TodoList案例_删除一个todo

需要理解的概念有:

  • 所有删除都需要确认
  • 更新状态需要复制对象
  • 事件绑定时event与自定义参数传递的两种形式
  • 属性类型与必要性约束

src/components/Item/index.js

import React, { Component } from 'react';
import './index.css';export default class Item extends Component {state = {mouse: false,};render() {const { mouse } = this.state;const { id, name, done } = this.props;return (<listyle={{ backgroundColor: mouse ? '#ddd' : '#fff' }}onMouseEnter={() => this.handleMouse(true)}onMouseLeave={() => this.handleMouse(false)}><label>{/*checkbox设置checked会报警告信息根据建议换成defaultChecked属性*/}<input type='checkbox' checked={done} onChange={this.update(id)} /><span>{name}</span></label><buttonclassName='btn btn-danger'onClick={() => this.handleDelete(id)}style={{ display: mouse ? 'block' : 'none' }}>删除</button></li>);}handleMouse = (flag) => {this.setState({ mouse: flag });};update = (id) => {return (e) => {this.props.updateTodo(id, e.target.checked);};};handleDelete = (id) => {if (window.confirm('确认删除吗?')) {this.props.deleteTodo(id);}};
}

src/components/List/index.js

import React, { Component } from 'react';
import Item from '../Item';
import './index.css';export default class List extends Component {render() {const { todos, updateTodo, deleteTodo } = this.props;return (<ul className='todo-main'>{todos.map((todo) => {// return <Item key={todo.id} id={todo.id} name={todo.name} done={todo.done} />;// 利用展开式参数传递进行批量属性传递return <Item key={todo.id} {...todo} updateTodo={updateTodo} deleteTodo={deleteTodo} />;})}</ul>);}
}

src/App.js

import React, { Component } from 'react';
import Header from './components/Header';
import Footer from './components/Footer';
import List from './components/List';
import './App.css';// 统一修改成类组件
class App extends Component {// 初始化状态state = {todos: [{ id: '001', name: '吃饭', done: true },{ id: '002', name: '睡觉', done: false },{ id: '003', name: '敲代码', done: true },],};render() {// 解构赋值const { todos } = this.state;return (<div className='todo-container'><div className='todo-wrap'><Header addTodo={this.addTodo} /><List todos={todos} updateTodo={this.updateTodo} deleteTodo={this.deleteTodo} /><Footer /></div></div>);}updateTodo = (id, done) => {/*// 禁止使用非setState的形式去修改state中的数据// 如下代码就是典型的违反上述原则案例console.log(id, done);// todos 从this.state进行解构赋值以后,不再是state的todosconst { todos } = this.state;// 修改todos也不是修改state里的todostodos.map((todoObj) => {if (todoObj.id === id) todoObj.done = done;return todoObj;});this.setState({ todos });*/const todos = this.state.todos;const newTodos = todos.map((todoObj) => {if (todoObj.id === id) return { ...todoObj, done };return todoObj;});console.log(todos);console.log(newTodos);this.setState({ todos: newTodos });};// addTodo用于添加一个todo,接收的参数是一个todo对象addTodo = (todoObj) => {const { todos } = this.state;// 追加一个todoconst newTodos = [todoObj, ...todos];// 更新状态this.setState({todos: newTodos,});};deleteTodo = (id) => {// 获取原来的todosconst { todos } = this.state;// 删除指定id的对象const newTodos = todos.filter((todoObj) => {return todoObj.id !== id;});// 更新状态this.setState({ todos: newTodos });};
}export default App;

八 TodoList案例_清除所有已完成

react todolist,需要理解的概念有:

  • 数组的filter过滤操作
  • 数组的其它操作函数的应用

src/App.js

import React, { Component } from 'react';
import Header from './components/Header';
import Footer from './components/Footer';
import List from './components/List';
import './App.css';// 统一修改成类组件
class App extends Component {// 初始化状态state = {todos: [{ id: '001', name: '吃饭', done: true },{ id: '002', name: '睡觉', done: false },{ id: '003', name: '敲代码', done: true },],};render() {// 解构赋值const { todos } = this.state;return (<div className='todo-container'><div className='todo-wrap'><Header addTodo={this.addTodo} /><List todos={todos} updateTodo={this.updateTodo} deleteTodo={this.deleteTodo} /><Footer deleteAllDoneTodo={this.deleteAllDoneTodo} /></div></div>);}updateTodo = (id, done) => {/*// 禁止使用非setState的形式去修改state中的数据// 如下代码就是典型的违反上述原则案例console.log(id, done);// todos 从this.state进行解构赋值以后,不再是state的todosconst { todos } = this.state;// 修改todos也不是修改state里的todostodos.map((todoObj) => {if (todoObj.id === id) todoObj.done = done;return todoObj;});this.setState({ todos });*/const todos = this.state.todos;const newTodos = todos.map((todoObj) => {if (todoObj.id === id) return { ...todoObj, done };return todoObj;});console.log(todos);console.log(newTodos);this.setState({ todos: newTodos });};// addTodo用于添加一个todo,接收的参数是一个todo对象addTodo = (todoObj) => {const { todos } = this.state;// 追加一个todoconst newTodos = [todoObj, ...todos];// 更新状态this.setState({todos: newTodos,});};deleteTodo = (id) => {// 获取原来的todosconst { todos } = this.state;// 删除指定id的对象const newTodos = todos.filter((todoObj) => {return todoObj.id !== id;});// 更新状态this.setState({ todos: newTodos });};deleteAllDoneTodo = () => {const newTodos = this.state.todos.filter((todoObj) => !todoObj.done);this.setState({todos: newTodos,});};
}export default App;

src/components/Footer/index.js

import React, { Component } from 'react';
import './index.css';
export default class Footer extends Component {render() {return (<div className='todo-footer'><label><input type='checkbox' /></label><span><span>已完成0</span> / 全部2</span><button onClick={this.deleteAllDone} className='btn btn-danger'>清除已完成任务</button></div>);}deleteAllDone = () => {this.props.deleteAllDoneTodo();};
}

九 数组reduce方法

需要理解的概念有:

  • 数组reduce方法
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8" /><title>数组的reduce方法</title>
</head>
<body><script type="text/javascript">
//#region
/*
数组的reduce方法(很常用):
语法:arr.reduce((preValue, current, index, arr) => {} ,initialValue)preValue:第一次执行回调时为给定的初始值initialValue,以后是上一次执行回调时的返回值。备注:若没有传入initialValue,则第一次的preValue值是数组中第一个元素的值。current 表示当前正在处理的元素;initialValue 表示初始值。一般做数学运算时设置为0,若为筛选最值可以不传。arr:当前操作的数组index 表示当前正在处理的数组元素的索引,若传入了initialValue值,则为0,否则为1;
*/
//#endregionlet arr = [9, 1, 20, 3, 4, 5, 6, 7, 8, 9, 10]let persons = [{ id: '001', name: '老刘1', age: 18 },{ id: '001', name: '老刘2', age: 14 },{ id: '001', name: '老刘3', age: 15 },{ id: '001', name: '老刘4', age: 22 },]// const x = persons.reduce((pre,curr)=>{// 	return pre + (curr.age > 15 ? 1 : 0)// },0)// console.log(x)// 做累加器使用----求出数组所有元素的和/* const x = arr.reduce((preValue,current)=>{// console.log(preValue,current)return preValue + current}) */// 条件统计 ---- 求出数组中偶数有几个/* const x = arr.reduce((preValue,current)=>{return preValue + (current % 2 === 0 ? 1 : 0 )},0) */// 条件求和 ---- 求出数组中所有偶数的和/* const x = arr.reduce((preValue,current)=>{return preValue + (current % 2 === 0 ? current : 0 )},0) */// 筛选最值/* const x = arr.reduce((preValue,current)=>{return Math.max(preValue,current)}) */</script>
</body></html>

十 TodoList案例_完成底部功能

需要理解的概念有:

  • 数组map遍历
  • 函数单行代码与多行代码的差异
  • 对象合并
  • checkbox状态值的获取
  • 函数属性的传递与接收使用

react lazy、src/App.js

import React, { Component } from 'react';
import Header from './components/Header';
import Footer from './components/Footer';
import List from './components/List';
import './App.css';// 统一修改成类组件
class App extends Component {// 初始化状态state = {todos: [{ id: '001', name: '吃饭', done: true },{ id: '002', name: '睡觉', done: false },{ id: '003', name: '敲代码', done: true },],};render() {// 解构赋值const { todos } = this.state;return (<div className='todo-container'><div className='todo-wrap'><Header addTodo={this.addTodo} /><List todos={todos} updateTodo={this.updateTodo} deleteTodo={this.deleteTodo} /><FooterdeleteAllDoneTodo={this.deleteAllDoneTodo}todos={todos}updateAllTodo={this.updateAllTodo}/></div></div>);}updateTodo = (id, done) => {/*// 禁止使用非setState的形式去修改state中的数据// 如下代码就是典型的违反上述原则案例console.log(id, done);// todos 从this.state进行解构赋值以后,不再是state的todosconst { todos } = this.state;// 修改todos也不是修改state里的todostodos.map((todoObj) => {if (todoObj.id === id) todoObj.done = done;return todoObj;});this.setState({ todos });*/const todos = this.state.todos;const newTodos = todos.map((todoObj) => {if (todoObj.id === id) return { ...todoObj, done };return todoObj;});console.log(todos);console.log(newTodos);this.setState({ todos: newTodos });};// addTodo用于添加一个todo,接收的参数是一个todo对象addTodo = (todoObj) => {const { todos } = this.state;// 追加一个todoconst newTodos = [todoObj, ...todos];// 更新状态this.setState({todos: newTodos,});};deleteTodo = (id) => {// 获取原来的todosconst { todos } = this.state;// 删除指定id的对象const newTodos = todos.filter((todoObj) => {return todoObj.id !== id;});// 更新状态this.setState({ todos: newTodos });};deleteAllDoneTodo = () => {const newTodos = this.state.todos.filter((todoObj) => !todoObj.done);this.setState({todos: newTodos,});};updateAllTodo = (done) => {const newTodos = this.state.todos.map((todoObj) => {return { ...todoObj, done };});this.setState({todos: newTodos,});};
}export default App;

src/components/Footer/index.js

import React, { Component } from 'react';
import './index.css';
export default class Footer extends Component {render() {const { todos } = this.props;const doneCount = todos.reduce((pre, curr) => pre + (curr.done ? 1 : 0), 0);return (<div className='todo-footer'><label><inputtype='checkbox'checked={todos.length === doneCount && todos.length > 0}onChange={this.updateAll}/></label><span><span>已完成{doneCount}</span> / 全部{todos.length}</span><button onClick={this.deleteAllDone} className='btn btn-danger'>清除已完成任务</button></div>);}deleteAllDone = () => {this.props.deleteAllDoneTodo();};updateAll = (e) => {this.props.updateAllTodo(e.target.checked);};
}

十一 总结TodoList案例

需要理解的概念有:

(1)拆分组件时,要拆到位,结构、样式都要拆。
(2)组件化编码流程:1. 拆分组件: 根据功能抽取组件2. 实现静态组件: 使用组件实现静态页面效果3. 实现动态组件3.1 动态显示初始化数据3.1.1 数据类型3.1.2 数据名称3.1.2 保存在哪个组件?3.2 交互(从绑定事件监听开始)
(3)src/App.css放程序员写的公共样式
(4)public/css/bootstrap.css放成型的第三方公共样式
(5)关于react中<input type="checkbox">的checked属性与defaultChecked1.checked属性,时时刻刻起作用,而且必须配合disabled或onChange使用,否则就不能改了。2.defaultChecked属性,只起一次作用,可以单独使用 (不建议使用)
(6)关于父子之间通信:1.【父组件】给【子组件】传递数据:通过props传递2.【子组件】给【父组件】传递数据:通过props传递,要求父提前给子传递一个函数
(7)使用//eslint-disable-next-line可以临时关闭下一行的语法检查
(8)熟练使用数组的reduce方法
{const { todos } = this.props;const doneCount = todos.reduce((pre, curr) => pre + (curr.done ? 1 : 0), 0);return (<div className='todo-footer'><label><inputtype='checkbox'checked={todos.length === doneCount && todos.length > 0}onChange={this.updateAll}/></label><span><span>已完成{doneCount}</span> / 全部{todos.length}</span><button onClick={this.deleteAllDone} className='btn btn-danger'>清除已完成任务</button></div>);}deleteAllDone = () => {this.props.deleteAllDoneTodo();};updateAll = (e) => {this.props.updateAllTodo(e.target.checked);};
}

十一 总结TodoList案例

需要理解的概念有:

(1)拆分组件时,要拆到位,结构、样式都要拆。
(2)组件化编码流程:1. 拆分组件: 根据功能抽取组件2. 实现静态组件: 使用组件实现静态页面效果3. 实现动态组件3.1 动态显示初始化数据3.1.1 数据类型3.1.2 数据名称3.1.2 保存在哪个组件?3.2 交互(从绑定事件监听开始)
(3)src/App.css放程序员写的公共样式
(4)public/css/bootstrap.css放成型的第三方公共样式
(5)关于react中<input type="checkbox">的checked属性与defaultChecked1.checked属性,时时刻刻起作用,而且必须配合disabled或onChange使用,否则就不能改了。2.defaultChecked属性,只起一次作用,可以单独使用 (不建议使用)
(6)关于父子之间通信:1.【父组件】给【子组件】传递数据:通过props传递2.【子组件】给【父组件】传递数据:通过props传递,要求父提前给子传递一个函数
(7)使用//eslint-disable-next-line可以临时关闭下一行的语法检查
(8)熟练使用数组的reduce方法

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/5/40126.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息