react todolist 3

功能:1.输入框输入事项,点击add,list增加一条,输入框清空并且聚焦;

2.点击当前checkbox,勾选文字为已完成,取消勾选文字为未完成;

父组件TodoList.js

分成了三个子组件

TodoHeader,TodoInput,List

 

import React, { Component } from 'react';
import{TodoInput,TodoHeader,List} from './index.js'

class TodoList extends Component {
  constructor(){
    super()
    this.state={
      title2:"今日事今日毕",
      todos:[{
        id:1,
        title:"吃饭",
        isComleted:true
      },
      { 
        id:2,
        title:"学习",
        isComleted:true
      },
      { 
        id:3,
        title:"睡觉",
        isComleted:false
      },
    ]
    }
  }
  render() {
    return (
      <div className="App">
        <TodoHeader title='待办事项'>
          {this.state.title2}
        </TodoHeader>
        <TodoInput btnText='add' addTodo={this.addTodo}/>
        <List todo={this.state.todos} onisComletedChange={this.onisComletedChange}></List>
      </div>
    );
  }

  addTodo=(todoTitle)=>{
    console.log('子元素传值',todoTitle)
    //注意不能用push这样写,因为push返回的是数组的长度
    // this.setState({
    //   todos:this.state.todos.concat({
    //     id:Math.random(),
    //     title:todoTitle,
    //     isComleted:false
    //   })
    // })
    //用push这样写
    // const newTodos = [...this.state.todos]
    // newTodos.push({
    //     id:Math.random(),
    //     title:todoTitle,
    //     isComleted:false
    // })
    // this.setState({
    //   todos:newTodos
    // })

    //第三种新值添加进数组的方法
    const newlist = {
      id:Math.random(),
      title:todoTitle,
      isComleted:false
    }
    this.setState({
      todos:[...this.state.todos,newlist]
    })
  }

  
  //点击checkbox取反
  onisComletedChange=(id)=>{
    console.log(id)
    const data = this.state.todos.map(item=>{
      if(item.id===id){
        item.isComleted=!item.isComleted
      }
      return item
    })
    this.setState({
      todos:data
    })
  }

}

export default TodoList

TodoHeader.js

import React, { Component } from 'react';

export default class TodoHeader extends Component {
  render() {
    console.log(this.props) //{title: "待办事项", children: "今日事今日毕"}
    return (
      <div> 
        <h1>{this.props.title}</h1>
        <p>{this.props.children}</p>
      </div>
    );
  }
}

TodoInput.js

import React, { Component,createRef } from 'react';

export default class TodoInput extends Component {
  constructor(){
    super()
    this.state={
        inputValue:''
    }
    this.handleAdd = this.handleAdd.bind(this)
    this.handleKeyUp = this.handleKeyUp.bind(this)
    //定义createRef
    this.inputDom = createRef()
  }
  render() {
    return (
      <div> 
        <input type="text"
               value={this.state.inputValue}
               onChange={this.handleInput.bind(this)}
               onKeyUp={this.handleKeyUp}
               ref={this.inputDom}
        />
        <button onClick={this.handleAdd}>{this.props.btnText}</button>
      </div>
    );
  }

  //点击添加从state中获取最新值 输入框聚焦this.inputDom.current.focus()
  handleAdd(){
    if(this.state.inputValue ===''){
      return
    }else{
      //接收父组件addTodo事件,并将input参数传递给父元素
      this.props.addTodo(this.state.inputValue)
      console.log('inputDom',this.inputDom)
      this.setState({
        inputValue:""
      },()=>{
        this.inputDom.current.focus()
      })
    }
  }

  //获取input的值,并交给state 
  handleInput(e){
    // console.log(e.currentTarget.value)
    this.setState({
      inputValue:e.currentTarget.value
    })
  }

  //回车输入
  handleKeyUp(e){
    // console.log(e.keyCode)
    if(e.keyCode ===13){
       this.handleAdd()

       this.setState({
        inputValue:""
      })
    }
    
  }
}

List.js

import React, { Component } from 'react';
//引入类型检查插件
import PropTypes from 'prop-types'

export default class List extends Component {
 //父元素类型验证 验证todo是否是array,以及内部各项的数据类型验证
  static propTypes = {
      todo:PropTypes.arrayOf(PropTypes.shape({
          id:PropTypes.number.isRequired,
          title:PropTypes.string.isRequired,
          isComleted:PropTypes.bool.isRequired,
      })).isRequired
  }
  render() {
    console.log(this.props.todo) //父组件传来的todo
    let todo = this.props.todo
    return (
      <div> 
            {
                todo.map(item=>{
                return <div key={item.id}>{item.title}
                    <input 
                        style={{marginLeft:'30px'}} 
                        type="checkbox"
                        checked={item.isComleted}   //默认true的选中
                        onChange={this.handleBoxChange.bind(this,item.id)}  //当前点击的id传给onChange事件
                    />
                    <span>{item.isComleted?'已完成':'未完成'}</span>
                </div> 
                })
            }
      </div>
    );
  }
    handleBoxChange(id){
        //  console.log(id)
        this.props.onisComletedChange(id) //接收父元素的事件并传值
        
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值