React实现TodoList功能代码

TodoList.js

import React, { Component, Fragment } from 'react'
import TodoItem from './TodoListItem'
import './style.css'

class TodoList extends Component {
  constructor(props) {
    super(props)
    this.state = {
      inputValue: '',
      list: []
    }
    this.handleInputChange = this.handleInputChange.bind(this)
    this.handleKeyDown = this.handleKeyDown.bind(this)
    this.handleBtnClick = this.handleBtnClick.bind(this)
    this.handleItemDelete = this.handleItemDelete.bind(this)
  }
  render() {
    return (
      <Fragment>
        {
          /**这是注释,在html中
           * 用htmlFor代替for,
           * 用className代替class
           * 来避免和JS的相关关键字冲突*/
        }
        <div>
          <label htmlFor="inputArea">输入框</label>
          <input
            autoFocus
            id="inputArea"
            className="test"
            value={this.state.inputValue}
            onChange={this.handleInputChange}
            onKeyDown={this.handleKeyDown} />
          <button onClick={this.handleBtnClick}>提交</button>
        </div>
        <ul>
          {this.getTodoItem()}
        </ul>
      </Fragment>
    )
  }
  getTodoItem() {
    return this.state.list.map((item, index) => {
      return (
        <TodoItem key={index} item={item} index={index} deleteItem={this.handleItemDelete} />
      )
    })
  }
  handleInputChange(e) {
    const value = e.target.value
    this.setState(() => ({
      inputValue: value
    }))
  }
  handleBtnClick() {
    /**不能直接操作state中的数据,
     * 如果用this.state.list.push(this.state.inputValue)会报错
     * 最好是使用ES6中的展开运算符
     * list: [...this.state.list, this.state.inputValue],
     * 同步的写法
     * this.setState({
     * list: [...this.state.list, this.state.inputValue],
     * inputValue: ''
     * })
     * 推荐异步的写法*/
    this.setState((prevState) => ({
      list: [...prevState.list, prevState.inputValue],
      inputValue: ''
    }))
  }
  handleItemDelete(index) {
    /**immutable规范
     * state不允许直接改变,会影响性能优化*/
    const list = [...this.state.list]
    list.splice(index, 1);
    this.setState({
      list: list
    })
  }
  handleKeyDown(e) {
    if (e.keyCode === 13)
      this.handleBtnClick()
  }
}

export default TodoList

TodoItem.js

import React, { Component } from 'react'
import PropTypes from 'prop-types'

class TodoItem extends Component {
  constructor(props) {
    /**当组件的state或props发生改变的时候
     * render函数就会重新执行*/
    super(props)
    this.handleItemClick = this.handleItemClick.bind(this)
  }
  render() {
    const { item } = this.props
    return (
      <li onClick={this.handleItemClick}>{item}</li>
    )
  }
  handleItemClick() {
    const { deleteItem, index } = this.props
    deleteItem(index)
  }
}
/**属性校验 */
TodoItem.propTypes = {
  item: PropTypes.string.isRequired,//必传
  deleteItem: PropTypes.func,
  index: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
}

/**为属性设置默认值 */
TodoItem.defaultProps = {
  test: 'hello world'
}

export default TodoItem

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import TodoList from './TodoList';

ReactDOM.render(<TodoList />, document.getElementById('root'));

转载于:https://my.oschina.net/startjcu/blog/3049330

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值