使用react实现一个todolist

效果如下:


image.png

分析组件:
1.头部:标题
2.内容:列表项+删除
3.尾部:添加列表项
4.包裹所有组件的App.js,在这个大的组件包含所有的属性及操作


image.png

标题

//header.js
import React,{Component } from 'react';
import "./header.css"

class Header extends Component{
    render(){
        return (
            <div className="header">
                任务便签
            </div>
        )
    }
}
export default Header

在App.js引出:

<Header />

尾部添加

分析:
1.因为所有的操作都会在App.js里面去操作,所以子组件的所以初始化的属性都需要通过父组件传值给子组件;比如输入框的value属性值
2.通过onChange事件获取用户输入的值,试想:怎么让用户输入的值显示在输入框里面呢:也就是说我怎么把输入的值赋值给父组件的value,这就需要使用子组件触发父组件的函数,并传值给父组件:this.props.这个方法(传的值)
3.当点击添加按钮的时候,我需要将输入的值追加到定义的List,同样在子组件点击按钮,触发父组件的方法
footer.js

class Header extends Component{
        handleInput(e){
          this.props.handleInput(e.target.value)
        }
        handleAdd(){
          this.props.handleAdd()
        }
     render(){
        return (
            <div className="footer">
                <input type="text" value={this.props.value} onChange={this.handleInput.bind(this)}>
                              <button onChlick={this.handleAdd.bind(this)}>添加</button>
            </div>
        )
    }
}
//父组件
constructor(props) {
        super(props)
        this.state = {
            list: [{
                name: 'learn english',
                status: 0
            }, {
                name: 'Learn guitar',
                status: 0
            }, {
                name: 'weight less than 100',
                status: 0
            }, {
                name: 'have 100,000 deposit',
                status: 0
            }],
            value:"",
        }
    }
//父组件接受子组件传的值
handleInput(val){
  this.setData({
    value:val
  })
}
handleAdd(){
  if(!this.state.value){
    return false
  }
  this.setState({
    list:[...this.state.list,{
      name:this.state.value,
      status:0,
    }],
  value:""
  })
}
render{
  return (
  <Footer value={this.state.list} handleInput={this.handleInput.bind(this)} handleAdd={this.handleAdd.bind(this)}  />
)
}

中间列表项

分析:
1.列表项是由一个单选框,名字,删除按钮
2.因为列表项可能会有很多,则使用map方法
3.单选框的选中状态是由List的status为1才表示已选中,当选中状态发生改变时,怎么让list的status实时去改变呢,所以需要出发父组件的方法,
4.当该列表项为选中时,则该文字会加上删除线:利用text-decoration-line:值为"line-through"时表示文字中间部分画线
5.点击删除按钮是需要删除当前用户点击的那一行,所以怎么判断用户是当前那一行是一个问题:
6.已完成的数量是表示status为1的个数

// this.handleclick.bind(this,要传的参数)  handleclick(传过来的参数,event)
class ListItem extends Component{
    handleFished(name){
        // 子组件向父组件传值
        // 在子组件点击的li得到的值,交给父组件去做交互
        this.props.handleFished(name);
    }
    handleDelete(name){
        this.props.handleDelete(name)
    }
    render(){
        return (
            <ul>
                {this.props.data.map((item,index)=>{
                    return (
                        <li key={index} className="listItem">
                            <input type="checkbox" checked={item.status===1} onChange={this.handleFished.bind(this,item.name)} />
                            <span style={{textDecorationLine:item.status===0?'none':'line-through'}}>{item.name}</span>
                            <button className="delete" onClick={this.handleDelete.bind(this,item.name)}>删除</button>
                        </li>
                    )
                })}
                <li>已完成:{this.props.finished}/总数:{this.props.data.length}</li>
            </ul>
        )
    }
}
export default ListItem

父组件:

constructor(props) {
        super(props)
        this.state = {
            list: [{
                name: 'learn english',
                status: 0
            }, {
                name: 'Learn guitar',
                status: 0
            }, {
                name: 'weight less than 100',
                status: 0
            }, {
                name: 'have 100,000 deposit',
                status: 0
            }],
            finished:0,//已完成的个数
        }
}
handleFished(name){
  const list=[];
  let sum=0;
  this.state.list.forEach((item,index){
    //判断用户点击的是当前所点击的那一行
    if(item.name=name){
      let val=this.state.list[index]
      let obj={
        name:val.name,
        status:val.status===0?1:0
      }
      list.push(Object.assign({},obj))
      this.setState({
        list:list
      },()=>{
        this.state.list.forEach(item=>{
          if(item.status===1){
            sum++;
          }
          this.setState({
            finished:sum
          })
        })
      })
    } else{
      list.push(item)
    }
  })

}
handleDelete(name){
  let arr=this.state.list.filter((item)=>{
            return item.name!==name
        })
        this.setState({
            list:arr
        })
}
render(){
  return(
    <ListItem data={this.state.list} finished={this.state.finished} handleFished={this.handleFished.bind(this)} handleDelete={this.handleDelete.bind(this)}  />
  )
}

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容