石家庄公司网站设计,论坛交流平台,深圳市门户网站建设企业,苏州网站开发网站建立费用useReducer和useContext前面有单独介绍过#xff0c;上手不难#xff0c;现在我们把这两个api结合起来使用#xff0c;该怎么用#xff1f;还是结合之前的简易增删改查的demo#xff0c;熟悉vue的应该可以看出#xff0c;useReducer类似于vuex#xff0c;useContext类似…useReducer和useContext前面有单独介绍过上手不难现在我们把这两个api结合起来使用该怎么用还是结合之前的简易增删改查的demo熟悉vue的应该可以看出useReducer类似于vuexuseContext类似于vue中的inject和provided,来分析下思路。
实现效果
代码实现
文件拆解 组件入口文件 - index.js
import { TasksContext, TasksDispatchContext } from ./context;
import { useReducer } from react;
import { initialTasks } from ./taskLists;
import { taskReucers } from ./tasksReducer;
import AddTask from ./AddTask;
import TaskList from ./TaskList;
function State() {const [tasks, dispatch] useReducer(taskReucers, initialTasks);return (TasksContext.Provider value{tasks}TasksDispatchContext.Provider value{dispatch}AddTask /TaskList //TasksDispatchContext.Provider/TasksContext.Provider);
}export default State;AddTask.js
import { useState, useContext } from react;
import { TasksDispatchContext } from ./context;
let nextId 3;function AddTask() {let [msg, setMsg] useState();const dispatch useContext(TasksDispatchContext);const handleSubmit () {if (!msg) return;setMsg();dispatch({type: added,task: {id: nextId,text: msg,done: false,},});};const handleChange (e) {setMsg(e.target.value);};return (input typetext value{msg} onChange{handleChange} /button onClick{handleSubmit}添加/button/);
}export default AddTask;
context.js文件
import { createContext } from react;export const TasksContext createContext(null);
export const TasksDispatchContext createContext(null);taskReucers.js
export function taskReucers(state [], action) {switch (action.type) {case added:return [...state, action.task];case changed:return state.map((task) {if (task.id action.task.id) {return action.task;} else return task;});case deleted:return state.filter((task) task.id ! action.task.id);default:throw new Error(Action type not found);}
}taskListsData.js
export const initialTasks [{ id: 0, text: Philosopher’s Path, done: true },{ id: 1, text: Visit the temple, done: false },{ id: 2, text: Drink matcha, done: false },
];TaskList.js
import { useState, useContext } from react;
import Task from ./Task;
import { TasksContext } from ./context;function TaskList() {const [isEdit, setIsEdit] useState(false);const tasks useContext(TasksContext);const handleChangeValue (value) {};return (ul{tasks.map((task) {return Task key{task.id} task{task} /;})}/ul);
}export default TaskList;Task.js
import { useState, useContext } from react;
import { TasksDispatchContext } from ./context;
function Task({ task }) {const [isEdit, setIsEdit] useState(false);const dispatch useContext(TasksDispatchContext);let todoContent ;function handleChangeText(e) {dispatch({ type: changed, task: { id: task.id, text: e.target.value } });}function handleDeleteTask(id) {dispatch({ type: deleted, task: { id } });}if (isEdit) {todoContent (spaninput typetext value{task.text} onChange{handleChangeText} /button onClick{() setIsEdit(false)}完成/button/span);} else {todoContent (spanspan{task.text}/spanbutton onClick{() setIsEdit(true)}编辑/button/span);}return (li{todoContent}button onClick{() handleDeleteTask(task.id)}删除/button/li);
}export default Task;这样拆解后明显的业务更加清晰容易维护了给后续接手的人一目了然的理解思路。 没有了组件层级之间的繁琐的层层传递数据和方法代码结构也很清晰了。 进一步的优化业务代码
context.js的封装
import { createContext, useReducer } from react;
import { initialTasks } from ./taskListsData;
import { taskReucers } from ./tasksReducer;export const TasksContext createContext(null);
export const TasksDispatchContext createContext(null);export default function TasksProvider({ children }) {const [tasks, dispatch] useReducer(taskReucers, initialTasks);return (TasksContext.Provider value{tasks}TasksDispatchContext.Provider value{dispatch}{children}/TasksDispatchContext.Provider/TasksContext.Provider);
}入口文件index.js的优化
import AddTask from ./AddTask;
import TaskList from ./TaskList;
import TasksProvider from ./context;
function State() {return (TasksProviderAddTask /TaskList //TasksProvider);
}export default State;这样实现了同样的效果代码更加精简。