一、需求

需要使用一个 React 实现一个 Todo List,这个简单的要死。

但是现在使用 Hook 来实现两个基本组件,而使用的 Hook 则是 useState

github 地址:

效果:

GIF.gif

二、App.js

import React, { Component } from 'react';
import './App.css';
import Form from './components/Form';
import Item from './components/Item';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      list:[{
        computed: false,
        val: '初始化内容'
      }]
    }
  }
  addHandle = (val) => {
    this.setState({
      list: [{computed: false,val}].concat(this.state.list)
    });
  }
  render() {
    return (
      <div className="App">
        <Form add={this.addHandle}/>
        <div className={'list'}>
          {
            this.state.list.map((item, index) => {
              return <Item item={item} key={index} ></Item>
            })
          }
        </div>
      </div>
    );
  }
}

export default App;

二、Form 组件

Form.jsx

这个是表单组件主要是完成输入和添加操作

import './Form.css';

import React, {useState} from 'react';

 function Form(props) {
  const [value, setValue] = useState('');
  const clickHandle = () => {
    if (typeof props.add === 'function' && value.length > 0) {
      props.add(value);
    }
    setValue('');
  }
  return (
    <div className="wrapper">
      <input
       value={value} 
       onChange={(ev) =>{setValue(ev.target.value)}} 
       className="input"
       placeholder={'todo..'}
      />
      <button className={'btn'} onClick={clickHandle}>
        Add
      </button>
    </div>
  );
}


export default Form;

Form.css

.wrapper {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.input{
  width:80%;
  padding: 5px;
  height: 50px;
  color: #000000;
  font-size: 30px;
}
.btn{
  height: 50px;
  width: 20%;
  background-color: #cccccc;
  border:0;
  font-size: 30px;
}

三、Item 组件

承载每个 Item 主要操作是完成和未完成状态变更

Item.jsx

import React, {useState} from 'react';
import './Item.css';


function Item(props) {
  const [computed, setCompoted] = useState(props.item.computed);
  const clickHandle = () => {
    setCompoted(!computed);
  };
  return (
    <div className="item" onClick={clickHandle}>
      {
        !computed 
        ? <p >{props.item.val}</p> 
        : <s >{props.item.val}</s>
      }
    </div>
  );
}

export default Item;

Item.css

.item {
  width: 100%;
  margin-top: 20px;
  border: 1px solid #ff5000;
  padding: 10px;
  font-weight: 500;
  font-size: 20px;
}