文章目录
整体结构(组件思想)

一、App.js文件配置
import React, { Component } from 'react';
import Todo from './todo/Todo';
import Life from './Life';
class App extends Component {
constructor(props) {
super(props);
this.state = { }
}
render() {
return ( <div>
<Todo></Todo>
</div>);
}
}
export default App;
二、Header.js配置
import {createRef} from 'react'
const inp = createRef();
function Header (props){
return (<div>
<input ref={inp}/>
<button onClick={()=>{
props.onAdd(inp.current.value);
inp.current.value = '';
}}>添加</button>
</div>)
}
export default Header
三、Item.js文件配置
import React, { Component } from 'react';
class Item extends Component {
constructor(props) {
super(props);
this.state = {
status: 0,
temp: ''
}
}
sure=()=>{
this.props.onUpdate({...this.props.item,title:this.state.temp},this.props.item)
this.setState({status:0,temp:''})
}
render() {
const props = this.props;
return (<div>
{}
{this.state.status === 0 ?
<span>
<input type="checkbox"
onChange={(e) => {
props.onUpdate({
title: props.item.title,
done: e.target.checked
}, props.item)
}}
checked={props.item.done} />
<span className='content' onDoubleClick={()=>{
this.setState({status:1,temp:props.item.title})
}}> {props.item.title}</span>
{}
<button onClick={() => {
props.delItem(props.item);
}}>x</button>
</span> :
<span>
{}
<input value={this.state.temp} onChange={e=>{
this.setState({temp:e.target.value})
}} />
<button onClick={this.sure} >确定</button>
</span>}
</div>);
}
}
export default Item;
四、List.js配置
function List(props) {
return ( <div>
<h3>{props.title}</h3>
{props.children}
</div> );
}
export default List;
五、Todo.js文件配置
import React, { Component } from 'react';
import Header from './Header';
import List from './List';
import Item from './Item';
class Todo extends Component {
constructor(props) {
super(props);
this.state = {
todo:[
{title:"学习vue",done:true},
{title:"进击React",done:false}
]
}
}
onUpdate = (nval,oval)=>{
let todo = this.state.todo;
let idx = todo.findIndex(value=>value.title == oval.title);
todo[idx] = {...nval};
this.setState({todo});
}
onAdd = str =>{
let todo = this.state.todo;
todo.unshift({done:false,title:str});
this.setState({todo});
}
delItem = item=>{
let todo = this.state.todo;
let idx = todo.findIndex(value=>value.title === item.title);
todo.splice(idx,1);
this.setState({todo});
}
componentDidUpdate(prevProps, prevState) {
localStorage.setItem("todo",JSON.stringify(this.state.todo));
}
componentDidMount() {
let todo = localStorage.getItem("todo")||"[]";
todo = JSON.parse(todo);
this.setState({todo});
}
render() {
const todo = this.state.todo;
return ( <div>
<h1>todo组件</h1>
<Header onAdd={this.onAdd}></Header>
<List title="未完成">
{todo.filter(value=>!value.done)
.map(value=><Item
key={value.title}
delItem = {this.delItem}
onUpdate={this.onUpdate}
item={value}>
</Item>)}
</List>
<List title="已完成">
{todo.filter(value=>value.done)
.map(value=><Item
key={value.title}
delItem = {this.delItem}
onUpdate={this.onUpdate}
item={value}>
</Item>)}
</List>
</div> );
}
}
export default Todo;
六、效果展示
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AAtS8vtM-1649342533770)(https://mg-blog.csdnimg.cn/50fb74ce709e4888995ce34704cefc25.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6JC96Zuq6aOY6aOO,size_20,color_FFFFFF,t_70,g_se,x_16)]](https://file.cfanz.cn/uploads/png/2022/04/07/14/5d8MT466cB.png)