主页 > 其他  > 

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

【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 pleted }; } 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 pleted).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美化 pleted { 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 pleted, "todo-list": true, })} > <input type="checkbox" checked={todoList pleted} onChange={() => handleDoneItem(todoList)} /> <span className="todo-text">{todoList.title}</span> </span> <span className={classNames({ // completed: todoList pleted, "del-btn": todoList pleted, })} onClick={() => handleDelItem(todoList.id)} > del </span> </li> ); })} </ul> </> ); } export default TodoLists;
标签:

【react18】如何使用useReducer和useContext来实现一个todoList功能由讯客互联其他栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【react18】如何使用useReducer和useContext来实现一个todoList功能