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

【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;

http://www.kler.cn/a/556009.html

相关文章:

  • 低代码与开发框架的一些整合[2]
  • 清影2.0(AI视频生成)技术浅析(四):计算机视觉(CV)
  • ArcGIS Pro挖填方计算指南:全面解析与实施步骤
  • python 3.6.8支持的Django版本是多少?
  • 2025 新版Android Studio创建Java语言项目
  • Python爬虫实战:从零到一构建数据采集系统
  • pycharm将当前项目上传到github
  • 自己安装一台DeepSeek的服务器
  • MySQL 中慢查询的优化方案
  • 在mfc中使用自定义三维向量类和计算多个三维向量的平均值
  • 基于深度重塑的航拍目标检测增强网络
  • 手写数字识别的神经网络 2层神经网络的类 代码详解
  • 【电机控制器】ESP32-C3语言模型——DeepSeek
  • 大模型在中间件运维领域运用的思考
  • Docker 性能优化指南
  • Centos离线安装Docker引擎及Docker Compose(附一键卸载脚本)
  • Web 自动化测试提速利器:Aqua 的 Web Inspector (检查器)使用详解
  • RFID测温技术:电力设备安全监测的新利器
  • CMU Sphinx、Kaldi 和 Mozilla DeepSpeech 三个开源语音识别引擎的综合比较
  • 越权漏洞及其修复方法