当前位置: 首页 > news >正文

【react18】如何使用useReducer和useContext来实现一个todoList功能

重点知识点就是使用useReducer来攻坚小型的公共状态管理,useImmerReducer来实现数据的不可变

实现效果

请添加图片描述

实现代码

  • 项目工程结构
    在这里插入图片描述
  • App.js文件
import logo from "./logo.svg";
import "./App.css";
import TodoLists from "./comps/TodoLists";
import AddItem from "./comps/AddItem";
import todoListsContext from "./comps/todolistContext";
// import { useReducer } from "react";
import { useImmerReducer } from "use-immer";
import FooterCompo from "./comps/FooterCompo";

// function todoListsReducer(state, action) {
//   switch (action.type) {
//     case "CHANGE_INPUT_VALUE":
//       return {
//         ...state,
//         inputValue: action.payload,
//       };
//       break;
//     case "ADD_ITEM":
//       return { ...state, todos: [...state.todos, action.payload] };
//       break;
//     default:
//       return state;
//   }
// }
function todoListsReducer(state, action) {
  switch (action.type) {
    case "CHANGE_INPUT_VALUE":
      state.inputValue = action.payload;
      return state;

    case "ADD_ITEM":
      state.todos = [...state.todos, action.payload];
      return state;

    case "DONE_ITEM":
      state.todos = state.todos.map((todo) => {
        console.log(action, "done");
        if (todo.id === action.payload.id) {
          return { ...todo, completed: !action.payload.completed };
        }
        return todo;
      });
      return state;

    case "DELETE_ITEM":
      state.todos = state.todos.filter((todo) => todo.id !== action.payload);
      return state;

    default:
      return state;
  }
}

function App() {
  // const [store, dispatch] = useReducer(todoListsReducer, {
  //   inputValue: "",
  //   todos: [],
  // });
  const [store, dispatch] = useImmerReducer(todoListsReducer, {
    inputValue: "",
    todos: [],
  });
  return (
    <div className="App">
      <h1>TodoLists</h1>
      <todoListsContext.Provider value={store}>
        <AddItem dispatch={dispatch} />
        <TodoLists dispatch={dispatch} />
        <FooterCompo />
      </todoListsContext.Provider>
    </div>
  );
}

export default App;
  • AddItem组件
import { useContext } from "react";
import todoListsContext from "./todolistContext";
import { v4 as uuid } from "uuid";

function AddItem({ dispatch }) {
  const data = useContext(todoListsContext);
  const handleChangeInputValue = (e) => {
    dispatch({
      type: "CHANGE_INPUT_VALUE",
      payload: e.target.value,
    });
  };
  const handleAddItem = () => {
    if (!data.inputValue) {
      return alert("Please enter a valid item");
    }
    dispatch({
      type: "ADD_ITEM",
      payload: {
        id: uuid(),
        title: data.inputValue,
        completed: false,
      },
    });
    dispatch({
      type: "CHANGE_INPUT_VALUE",
      payload: "",
    });
  };
  return (
    <div>
      <input
        type="text"
        value={data.inputValue}
        placeholder="Enter item name"
        onChange={handleChangeInputValue}
      ></input>
      <button onClick={handleAddItem}>add list</button>
    </div>
  );
}

export default AddItem;
  • FooterCompo组件
import todoListsContext from "./todolistContext";
import { useContext } from "react";
import { useMemo } from "react";
function FooterCompo() {
  const { todos } = useContext(todoListsContext);
  const completedCount = useMemo(
    () => todos.filter((e) => e.completed).length,
    [todos]
  );
  const remain = useMemo(
    () => todos.length - completedCount,
    [todos, completedCount]
  );
  return (
    <div>
      <span>all: {todos.length}</span> <span>completed: {completedCount}</span>{" "}
      <span>todo: {remain}</span>
    </div>
  );
}

export default FooterCompo;
  • 使用createContext来创建公共状态
import { createContext } from "react";

const todoListsContext = createContext({});

export default todoListsContext;
  • UI美化
.completed {
    text-decoration: line-through;
    color: gray;
}
.todo-list{
  cursor: pointer;
}

.todo-text{
  margin: auto 10px auto 4px;
}
.del-btn{
  cursor: pointer;
  color: gray;
}
.todo-item{
  text-align: left;

}
  • TodoLists组件
import { useContext } from "react";
import todoListsContext from "./todolistContext";
import classNames from "classnames";
import "./todoLists.css";

function TodoLists({ dispatch }) {
  const data = useContext(todoListsContext);
  const handleDoneItem = (item) => {
    dispatch({ type: "DONE_ITEM", payload: item });
  };
  const handleDelItem = (id) => {
    dispatch({ type: "DELETE_ITEM", payload: id });
  };
  return (
    <>
      <ul>
        {data.todos.map((todoList) => {
          return (
            <li key={todoList.id} className="todo-item">
              <span
                className={classNames({
                  completed: todoList.completed,
                  "todo-list": true,
                })}
              >
                <input
                  type="checkbox"
                  checked={todoList.completed}
                  onChange={() => handleDoneItem(todoList)}
                />
                <span className="todo-text">{todoList.title}</span>
              </span>
              <span
                className={classNames({
                  // completed: todoList.completed,
                  "del-btn": todoList.completed,
                })}
                onClick={() => handleDelItem(todoList.id)}
              >
                del
              </span>
            </li>
          );
        })}
      </ul>
    </>
  );
}
export default TodoLists;

相关文章:

  • 通过Selenium实现UI自动化校验输入的数据是否完整有效方式
  • Unity Mixamo模型更好的适配角色模型
  • 【Gin-Web】Bluebell社区项目梳理2:JWT-Token认证
  • 【深度学习】自然语言处理(NLP)-语音识别-WaveNet
  • 虚函数与多态
  • 蓝桥云客 路径之谜
  • 算法——Boyer-Moore算法
  • 网络安全知识--网络、网络安全产品及密码产品概述
  • 最新版免安装免费动图录制与编辑利器
  • 知识库技术栈
  • css特异性,继承性
  • round的意思
  • Windows 图形显示驱动开发-查询 WDDM(3.2) 功能支持和启用
  • Maven导入hutool依赖报错-java: 无法访问cn.hutool.core.io.IORuntimeException 解决办法
  • QML ToolButton与DelayButton的使用、详解与自定义样式
  • Day32.
  • Linux 内核自旋锁spinlock(四)--- queued spinlock
  • ubuntu环境编译ffmepg支持nvidia显卡加速
  • Unity摄像机与灯光相关知识
  • 51c大模型~合集71
  • 推广普通话绘画/奉化网站关键词优化费用
  • 给企业做网站的公司西安/谷歌安装器
  • 网站集约化建设力度/百度seo排名点击器app
  • 怎么让百度收录你的网站/河南网站推广优化排名
  • 网站开发外包价格/百度查询关键词排名工具
  • 临沂网站建设培训学校/广州seo顾问