React case 1

1. Case requirements:

1. Realize component classification, divided into header input, list, and bottom

2. Realize the rendering of the input task name into the list

3. Delete tasks individually

4. Select all or not select all

5. Delete the checked task

2. Implementation principle

1. Complete the component creation

2. Bind the value of the input box through ref, and change the value of the rendered array in the list through setstate in the custom method parameter passed back to app.js

3. By confirming that the id value of the clicked element array is sent back to app.js, and then returning a new array whose id value is not the returned id value through the filter method, the delete function is realized

4. Change the value in the state by looping to judge the returned value to change the checked state

5. Create a method that judges whether it is checked by looping and then returns a new array through the filter method. Put the method on the bottom component and call it

3. Code:

App.js

/*
 * @Author: wu07 [email protected]
 * @Date: 2023-02-14 16:31:46
 * @LastEditors: wu07 [email protected]
 * @LastEditTime: 2023-02-17 09:27:23
 * @FilePath: \react\day05\demo02\tode\src\App.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import React, { Component } from 'react';
import Header from './components/Header';
import List from './components/List';
import Footer from './components/Footer';
import './App.css';
export default class App extends Component {
  state = {
    todos: [
      { id: '001', name: '吃饭', done: true },
      { id: '002', name: '睡觉', done: true },
      { id: '003', name: '打代码', done: false },
      { id: '004', name: '逛街', done: false }
    ]
  };
  addTodo = (e) => {
    const todos = this.state.todos;
    const newTodos = [e, ...todos];
    this.setState({ todos: newTodos });
  };

  change = (e) => {
    const todos = this.state.todos;
    this.setState({ todos: e });
  };
  updateTodo = (id, done) => {
    const { todos } = this.state;
    const newTodos = todos.map((todoObj) => {
      if (todoObj.id === id) return { ...todoObj, done };
      else return todoObj;
    });
    this.setState({ todos: newTodos });
  };
  Delete = (id) => {
    const todos = this.state.todos;
    const newTodos = todos.filter((e) => {
      return e.id !== id;
    });
    this.setState({ todos: newTodos });
  };
  delete = () => {
		const newTodos =this.state.todos.filter((e)=>{
			return !e.done
		})
		this.setState({todos:newTodos})
  };
  render() {
    return (
      <div className="todo-container">
        <div className="todo-wrap">
          <Header addTodo={this.addTodo} Delete={this.Delete} />
          <List todos={this.state.todos} updateTodo={this.updateTodo} Delete={this.Delete} />
          <Footer todos={this.state.todos} change={this.change} delete={this.delete} />
        </div>
      </div>
    );
  }
}

components/Footer/index.jsx

/*
 * @Author: wu07 [email protected]
 * @Date: 2023-02-14 16:36:54
 * @LastEditors: wu07 [email protected]
 * @LastEditTime: 2023-02-17 09:20:13
 * @FilePath: \react\day05\demo02\tode\src\components\Footer\index.jsx
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import React, { Component } from 'react';
import './index.css';
export default class Footer extends Component {
    state = {
        flag: false,
    };
    // (function name(params) {
    //     console.log(111);
    // }());
    allCheck = () => {
        this.state.flag = !this.state.flag;
        const todos = this.props.todos;
        todos.map((e) => {
            if (this.state.flag == true) {
                e.done = true;
            }
            else {
                e.done = false;
            }
        });
        this.props.change(todos);
    };
    delete = () => {
        this.props.delete();
    };
    render() {
        //pre初始值
        const doneCount = this.props.todos.reduce((pre, todo) => pre + (todo.done ? 1 : 0), 0);
        return (
            <div className="todo-footer">
                <label>
                    <input type="checkbox" checked={this.state.flag = doneCount == 4 ? true : false} onChange={this.allCheck} />
                </label>
                <span>
                    <span>已完成{doneCount}</span> / 全部{this.props.todos.length}
                </span>
                <button className="btn btn-danger" onClick={this.delete}>清除已完成任务</button>
            </div>
        );
    }
}

components/Footer/index.css

/*footer*/
.todo-footer {
    height: 40px;
    line-height: 40px;
    padding-left: 6px;
    margin-top: 5px;
}

.todo-footer label {
    display: inline-block;
    margin-right: 20px;
    cursor: pointer;
}

.todo-footer label input {
    position: relative;
    top: -1px;
    vertical-align: middle;
    margin-right: 5px;
}

.todo-footer button {
    float: right;
    margin-top: 5px;
}

components/List/index.jsx

/*
 * @Author: wu07 [email protected]
 * @Date: 2023-02-14 16:37:07
 * @LastEditors: wu07 [email protected]
 * @LastEditTime: 2023-02-15 17:22:04
 * @FilePath: \react\day05\demo02\tode\src\components\List\index.jsx
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import React, { Component } from 'react';
import './index.css';
import Item from '../Item';
export default class List extends Component {
    render() {
        const { todos, updateTodo, Delete } = this.props;
        return (
            <ul className="todo-main">
                {
                    todos.map(todo => {
                        return <Item key={todo.id} {...todo} updateTodo={updateTodo} Delete={Delete} />;
                    })
                }
            </ul>
        );
    }
}

components/List/index.css

/*main*/
.todo-main {
    margin-left: 0px;
    border: 1px solid #ddd;
    border-radius: 2px;
    padding: 0px;
}

.todo-empty {
    height: 40px;
    line-height: 40px;
    border: 1px solid #ddd;
    border-radius: 2px;
    padding-left: 5px;
    margin-top: 10px;
}

/*item*/
li {
    list-style: none;
    height: 36px;
    line-height: 36px;
    padding: 0 5px;
    border-bottom: 1px solid #ddd;
}

li label {
    float: left;
    cursor: pointer;
}

li label li input {
    vertical-align: middle;
    margin-right: 6px;
    position: relative;
    top: -1px;
}

li button {
    float: right;
    display: none;
    margin-top: 3px;
}

li:before {
    content: initial;
}

li:last-child {
    border-bottom: none;
}

components/Item/index.jsx

/*
 * @Author: wu07 [email protected]
 * @Date: 2023-02-14 16:37:05
 * @LastEditors: wu07 [email protected]
 * @LastEditTime: 2023-02-15 17:21:07
 * @FilePath: \react\day05\demo02\tode\src\components\Item\index.jsx
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import React, { Component } from 'react';
import './index.css';
export default class Item extends Component {
    state = {
        mouse: false
    };
    change = (e) => {
        this.props.updateTodo(this.props.id, e.target.checked);
    };
    Enter = () => {
        this.setState({
            mouse: true
        });
    };
    Leave = () => {
        this.setState({
            mouse: false
        });
    };
    Delete = () => { this.props.Delete(this.props.id); };


    render() {
        return (
            <div onMouseEnter={this.Enter} onMouseLeave={this.Leave}><li>
                <label>
                    <input type="checkbox" checked={this.props.done} onChange={this.change} />
                    <span>{this.props.name}</span>
                </label>
                <button className="btn btn-danger" style={
   
   { display: this.state.mouse ? 'block' : 'none' }} onClick={this.Delete}>删除</button>
            </li>
            </div>
        );
    }
}

components/Item/index.css

/*item*/
li {
    list-style: none;
    height: 36px;
    line-height: 36px;
    padding: 0 5px;
    border-bottom: 1px solid #ddd;
}

li label {
    float: left;
    cursor: pointer;
}

li label li input {
    vertical-align: middle;
    margin-right: 6px;
    position: relative;
    top: -1px;
}

li button {
    float: right;
    display: none;
    margin-top: 3px;
}

li:before {
    content: initial;
}

li:last-child {
    border-bottom: none;
}

components/Header/index.jxs

/*
 * @Author: wu07 [email protected]
 * @Date: 2023-02-14 16:37:03
 * @LastEditors: wu07 [email protected]
 * @LastEditTime: 2023-02-15 13:23:06
 * @FilePath: \react\day05\demo02\tode\src\components\Header\index.jsx
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import React, { Component } from 'react';
import './index.css';
import { nanoid } from 'nanoid';
export default class Header extends Component {
    handleKeyUp = (e) => {
        if (e.keyCode != 13) {
            return;
        }
        if (e.target.value.trim() === '') {
            alert("输入不能为空");
            return;
        }
        //nanoid()方法生成唯一id标识符
        const a = { id: nanoid(), name: e.target.value, done: false };
        this.props.addTodo(a);
        //清空输入
        e.target.value = '';
    };
    render() {
        return (
            <div className="todo-header">
                <input type="text" placeholder="请输入你的任务名称,按回车键确认" onKeyUp={this.handleKeyUp} />
            </div>
        );
    }
}

components/Header/index.css

/*header*/
.todo-header input {
    width: 560px;
    height: 28px;
    font-size: 14px;
    border: 1px solid #ccc;
    border-radius: 4px;
    padding: 4px 7px;
}

.todo-header input:focus {
    outline: none;
    border-color: rgba(82, 168, 236, 0.8);
    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
}

Four. Summary

In this small case, there are data transfer rendering and component import usage, which is suitable for friends who are beginners in react.

Guess you like

Origin blog.csdn.net/xiaowu1127/article/details/129092578