首先需要依据组件的结构拆分组件
分为Header, List, LiistItem , footer组件
App为根组件
App.js
// 采用类组件的写法
import React from 'react'
// import {
// Hello,
// Welcome
// } from './componnets'
import {
Header,
List,
Footer
} from './componnets'
class App extends React.Component {
// 状态在哪里操作状态的方法就在哪里
state = {
list: [
{id: '001', name: '吃饭', todo: false },
{id: '002', name: '睡觉', todo: true },
{id: '003', name: '敲代码', todo: true },
{id: '004', name: '打豆豆', todo: false },
{id: '005', name: '打游戏', todo: true }
]
}
// 添加
AddList = (name1) => {
let {list} = this.state;
console.log('name===', name1)
this.setState({
list: [name1, ...list]
})
}
// 更新
upDateList = (done, id) => {
let {list} = this.state;
let newList = list.map((item) => {
// 选择这个的时候,勾选单选框
if(item.id === id) return {...item, todo: done}
else return item
})
console.log("newList===", newList)
this.setState({
list: newList
})
}
// 删除
delteUpList = (id) => {
let { list } = this.state;
// 删除list的某一项
let newList = list.filter((listObj) => {
return listObj.id !== id
})
this.setState({
list: newList
})
}
// 所有已经勾选的
checkedAllTodo = (todo) => {
let { list } = this.state
// 加工数据
let newArr = list.map((item) => {
return {...item, todo}
})
this.setState({
list: newArr
})
}
// 清除已经完成的todolist
clearFisahedList = () => {
// 获取数据
let { list } = this.state
let newList = list.filter((item) => {
return !item.todo
})
this.setState({
list: newList
})
}
render () {
let { list } = this.state
return <div>
{/* <Hello/>
<Welcome/> */}
<Header todoList={this.AddList}/>
<List list={list} upDateList={this.upDateList} delteUpList={this.delteUpList}/>
<Footer list={list}
checkedAllTodo={this.checkedAllTodo}
clearFisahedList={this.clearFisahedList}></Footer>
</div>
}
}
export default App
Header组件(Header组件)
import PropTypes from 'prop-types';
import { nanoid } from 'nanoid'
import './index.css'
export default class Header extends Component {
keyUphNA = (event) =>{
let { keyCode,target } = event
if (event.keyCode !== 13) return
if (target.value.trim() === '') {
alert('请输入添加')
return
}
let obj = {id: nanoid(), name: target.value, todo: false}
this.props.todoList(obj)
target.value = ''
}
static propTypes = {
todoList: PropTypes.func
}
render() {
return (
<div className="Header">
<input type="text" placeholder='请输入你要输入的' onKeyUp={this.keyUphNA}/>
</div>
)
}
}
List组件
import React, { Component } from 'react'
import ListItem from '../ListItem'
import PropTypes from 'prop-types';
import './index.css'
export default class List extends Component {
static propTypes = {
list: PropTypes.array.isRequired,
upDateList: PropTypes.func.isRequired
}
render() {
let { list, upDateList, delteUpList } = this.props
return (
<div className="list_container">
{
list.map(todo => {
return <ListItem key={todo.id} {...todo}
upDateList={upDateList}
delteUpList={delteUpList}/>
})
}
</div>
)
}
}
ListIem组件是List的子组件
import React, { Component } from 'react'
import './index.css'
export default class ListItem extends Component {
state = {
mouse: false
}
// 用同一函数采用高阶函数 进入和离开的事件
handlermouse = (flag) => {
return () => {
console.log('flag===', flag)
this.setState({
mouse: flag
})
}
}
// 勾选和取消勾选触发的函数
changeHandler = (id) => {
return (event) => {
console.log('event, id', event.target.checked, id)
this.props.upDateList(event.target.checked, id)
}
}
deleteHandler = (id) =>{
console.log('id====', id)
if(window.confirm('你确定删除吗')) {
this.props.delteUpList(id)
}
}
render() {
let { id, name, todo } = this.props
let { mouse } = this.state
return (
<div className="list_item" onMouseEnter={this.handlermouse(true)}
onMouseLeave={this.handlermouse(false)}
style={{backgroundColor: mouse ? '#ddd': '#ccc'}}>
<input type="checkbox" checked={todo} onChange={this.changeHandler(id)}/>
<span>{ name }</span>
<button style={{display: mouse ? 'block': 'none'}}
onClick={() => this.deleteHandler(id)}>删除</button>
</div>
)
}
}
Footer组件
import React, { Component } from 'react'
import './index.css'
export default class Footer extends Component {
allChange = (event) => {
this.props.checkedAllTodo(event.target.checked)
}
clearAllList = () => {
console.log(`清除已经完成的`)
this.props.clearFisahedList()
}
render() {
let { list } = this.props;
// 总数
let allcount = list.length
// 已完成的数量
// let fished = 0;
// for(let i =0; i<list.length; i++) {
// if (list[i].todo) {
// fished += 1
// }
// }
let fished = list.reduce((pre, current) => {
return pre + (current.todo ? 1 : 0)
}, 0)
console.log('fished===', fished)
return (
<div className="footer">
<input type="checkbox"
checked={fished === allcount && allcount!==0 ? true : false}
onChange={this.allChange}/>
<span>已完成{fished}/总数{ allcount }</span>
<button onClick={this.clearAllList}>清楚已完成任务</button>
</div>
)
}
}
总结:
数据在哪里, 就在哪里写处理数据的方法
this.props.a 调用父组件中a的方法
react处理的三个核心: state, props, ref