其他分享
首页 > 其他分享> > TodoList-React

TodoList-React

作者:互联网

src文件
1.入口文件(index.js)

import React from 'react';//主要环境库es6
import ReactDOM from 'react-dom';//渲染dom环境
import Todo from './Todo'//引入组件
//渲染的dom
ReactDOM.render(
  <Todo></Todo>,
  document.getElementById('root')
);

2.多级传递数据(context.js)

// 使用context进行多级传递数据
// 1. createContext 创建一个可以多级传递的context数据
// 2. 使用 上一步创建的 conext ,提供一个 Provider 的提供器组件,把想要使用 context里面的数据的组件包起来
// 3. 在需要使用 context里面的数据的后代组件里面使用 Consumer 的组件来进行数据的获取
// Consumer只能使用函数的方式返回一个jsx结构来进行数据的渲染
import { createContext } from "react";

// context里面的默认数据
const defVal = (id) => {};
const TodoContext = createContext(defVal); //defVal 作用是 约定数据的格式

export default TodoContext;

3.todo.css

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
.todo {
  width: 600px;
  box-shadow: 0 0 4px 2px #ccc, 0 0 4px 2px #ccc inset;
  margin: 100px auto;
  padding: 20px;
}
.add {
  display: flex;
  padding: 40px;
}
.add input {
  width: 400px;
  height: 40px;
  outline: none;
  border: 1px solid #ccc;
  padding: 0 20px;
}
.add button {
  width: 100px;
}
.list {
  padding: 20px;
}
.item {
  display: flex;
  align-items: center;
  border-bottom: 1px dashed #ccc;
}
.item p {
  flex: 1;
  line-height: 40px;
  padding-left: 20px;
}

4.Todo.jsx(外层盒子组件)

// 这是最外层的组件
import React, { Component } from "react";
import TodoAdd from "./TodoAdd";
import TodoList from "./TodoList";
import "./todo.css";
// 导入 TodoContext
import TodoContext from "./context";
const { Provider, Consumer } = TodoContext;

// 父传子
// 1.自定义属性,2.在子组件里面使用props接收

// 子传父
// 1.自定义属性把一个可以修改父组件数据的方法传递给子组件
// 2.在子组件里面调用父组件传递进来方法来把数据传递回来

let id = 2;

export default class Todo extends Component {
  constructor(props) {
    super(props);
    this.state = {
      list: [
        { id: 1, content: "明天要下大雨", isDone: false },
        { id: 2, content: "后天上太阳", isDone: true },
      ],
    };
  }
  add(newVal) {
    //   得到原来的数据
    const list = this.state.list;
    // 修改过后
    list.push({ id: ++id, content: newVal, isDone: false });
    // 把新的数据set回去
    this.setState({
      list,
    });
  }
  //   用于删除的方法
  remove(id) {
    // 根据id得到数据对应的索引
    // Array.prototype.findIndex(item=>条件), 得到满足条件的第一个元素的索引
    const idx = this.state.list.findIndex((item) => item.id === id);
    // 根据索引使用splice方法删除
    const list = this.state.list;
    list.splice(idx, 1);
    this.setState({ list });
  }
  //用于input的反选
  alter(id, val, isDone) {
    const idx = this.state.list.findIndex((item) => item.id === id);
    // 根据索引使用splice方法替换
    const list = this.state.list;
    list.splice(idx, 1, { id: id, content: val, isDone: !isDone });
    this.setState({
      list,
    });
  }
  render() {
    return (
      <Provider
        value={{ del: this.remove.bind(this), alter: this.alter.bind(this) }}
      >
        {/* <Consumer>
          {(val) => {
            return <div>{val.length}</div>;
          }}
        </Consumer> */}
        <div className="todo">
          <h1>TodoListDemo</h1>
          {/* 用于添加的子组件 */}
          <TodoAdd addFn={this.add.bind(this)} />
          {/* 两个列表 */}
          {/* 正在进行 */}
          <TodoList
            data={this.state.list.filter((item) => !item.isDone)}
            title="正在进行"
          />
          {/* 已经完成 */}
          <TodoList
            data={this.state.list.filter((item) => item.isDone)}
            title="已经完成"
          />
        </div>
      </Provider>
    );
  }
}

5.TodoAdd.jsx(输入框)

// 实现添加功能的子组件
import React, { Component } from "react";
// 受控组件和非受控组件
// 受控 -- input表单受到state的控制

export default class TodoAdd extends Component {
  constructor(props) {
    super(props);
    console.log(this.props);
    this.state = {
      val: "",
    };
  }
  onClick() {
    // 修改父组件的数据 -- 子传父
    this.props.addFn(this.state.val);
    // 清空
    this.setState({ val: "" });
  }
  change(e) {
    //   把输入框的内容赋值给 state.val
    // 得到 内容
    // console.log(e.target.value);
    // 赋值
    this.setState({
      val: e.target.value,
    });
  }
  render() {
    return (
      <div className="add">
        <input
          type="text"
          value={this.state.val}
          onChange={this.change.bind(this)}
        />
        <button onClick={this.onClick.bind(this)}>添加</button>
      </div>
    );
  }
}

6.TodoList.jsx(未完成栏与已完成栏)

// 两个列表的子组件
import React, { Component } from "react";
import TodoListItem from "./TodoListItem";

export default class TodoList extends Component {
  // props 就是我们从父组件传递进来的数据
  constructor(props) {
    super(props);
    // console.log(props);    this.s
  }
  render() {
    return (
      <div className="list">
        <h2>{this.props.title}</h2>
        <TodoListItem data={this.props.data} />
      </div>
    );
  }
}

7.TodoListItem.jsx(其中的li)

// 每一荐事件的子组件
import React, { Component } from "react";
import TodoContext from "./context";
const { Consumer } = TodoContext;

export default class TodoListItem extends Component {
  render() {
    return (
      <Consumer>
        {(val) => (
          <div>
            {this.props.data.map((item) => (
              <div className="item" key={item.id}>
                <input
                  type="checkbox"
                  onChange={() => val.alter(item.id, item.content, item.isDone)}
                  checked={item.isDone}
                />
                <p>{item.content}</p>
                <span onClick={() => val.del(item.id)}>删除</span>
                {/* <Consumer>{(val) => <div>{typeof val}</div>}</Consumer> */}
              </div>
            ))}
          </div>
        )}
      </Consumer>
    );
  }
}

标签:val,TodoList,list,React,item,组件,import,id
来源: https://www.cnblogs.com/Gawainehzh/p/16120154.html