wordpress評論樓廣州百度seo排名
useReducer
和useContext
前面有單獨(dú)介紹過,上手不難,現(xiàn)在我們把這兩個(gè)api結(jié)合起來使用,該怎么用?還是結(jié)合之前的簡易增刪改查的demo,熟悉vue
的應(yīng)該可以看出,useReducer
類似于vuex
,useContext
類似于vue
中的inject
和provided
,來分析下思路。
實(shí)現(xiàn)效果
代碼實(shí)現(xiàn)
- 文件拆解
- 組件入口文件 -> 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 type="text" 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 = (<span><input type="text" value={task.text} onChange={handleChangeText} /><button onClick={() => setIsEdit(false)}>完成</button></span>);} else {todoContent = (<span><span>{task.text}</span><button onClick={() => setIsEdit(true)}>編輯</button></span>);}return (<li>{todoContent}<button onClick={() => handleDeleteTask(task.id)}>刪除</button></li>);
}export default Task;
這樣拆解后,明顯的業(yè)務(wù)更加清晰,容易維護(hù)了,給后續(xù)接手的人一目了然的理解思路。
沒有了組件層級之間的繁瑣的層層傳遞數(shù)據(jù)和方法,代碼結(jié)構(gòu)也很清晰了。
進(jìn)一步的優(yōu)化業(yè)務(wù)代碼
- 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的優(yōu)化
import AddTask from "./AddTask";
import TaskList from "./TaskList";
import TasksProvider from "./context";
function State() {return (<TasksProvider><AddTask /><TaskList /></TasksProvider>);
}export default State;
這樣實(shí)現(xiàn)了同樣的效果,代碼更加精簡。