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

react的状态管理简单钩子方法

1.recoil

useProvider文件:

import { atom, useRecoilState } from 'recoil';const initState = atom({key: 'initState',default: {state: [],},
})// 将业务逻辑拆分到一个单独文件中,方便进行状态管理
export interface StateProps {id: number;text: string;isFinished: boolean;
}
export interface ActionProps {type: string;[key: string]: any;
}
export const reducer = (state: StateProps[], action: ActionProps) => {console.log(state, action)switch (action.type) {case 'ADD':return [...state, action.todo];case 'CHANGESTATUS':return state.map(item => {if (item.id === action.id) {return Object.assign({}, item, { isFinished: !item.isFinished })}return item;});default:return state;}
}export const useProvider = () => {// 改变todoconst [context, dispatch]: any = useRecoilState(initState);const changeTodo = (id: number) => {const todoList = reducer(context.state, { type: 'CHANGESTATUS', id: id })dispatch({ state: todoList });}// 添加todoconst addTodo = (todo: StateProps) => {const todoList = reducer(context.state, { type: 'ADD', todo })dispatch({ state: todoList });}return { changeTodo, addTodo, todoList: context.state };
}

Todo组件:

import { TodoInput } from "./TodoInput";
import { TodoList } from "./TodoList";// 父组件
export const Todo = () => {return (<><TodoInput /><TodoList  /></>)
}

TodoInput组件:

import { useState } from "react";
import _ from 'lodash';
import { useProvider } from "./useProvider";// 子组件
export const TodoInput = () => {const [text, setText] = useState('');const {addTodo} = useProvider();const handleChangeText = (e: React.ChangeEvent) => {setText((e.target as HTMLInputElement).value);}const handleAddTodo = () => {if (!text) return;addTodo({id: new Date().getTime(),text: text,isFinished: false,})setText('');}return (<div className="todo-input"><input type="text" placeholder="请输入代办事项" onChange={handleChangeText} value={text} /><button style={{ marginLeft: '10px' }} onClick={handleAddTodo} >+添加</button></div>)
}

TodoItem组件:

import { useProvider } from "./useProvider";
import _ from 'lodash';// 孙子组件
export const TodoItem = ({ todo }: {todo:any;key: any;
}) => {const {changeTodo} = useProvider();// 改变事项状态const handleChange = () => {changeTodo(_.get(todo, 'id'));}return (<div className="todo-item"><input type="checkbox" checked={todo.isFinished} onChange={handleChange} /><span style={{ textDecoration: todo.isFinished ? 'line-through' : 'none' }}>{todo.text}</span></div>)
}

TodoList组件:

import { TodoItem } from "./TodoItem";
import { useProvider } from "./useProvider";
import _ from 'lodash';export const TodoList = () => {const {todoList} = useProvider();return (<div className="todo-list">{_.map(todoList, item => <TodoItem key={_.get(item, 'id')} todo={item||{}} />)}</div>)
}

然后在App组件引入Todo组件<Todo />

import { RecoilRoot } from 'recoil';
import './App.css';
import React from 'react';
import ErrorBoundary from './ErrorBoundary';
import { Todo } from './recoilProvider/Todo';const App:React.FC = ()=> {return (<RecoilRoot><ErrorBoundary><React.Suspense fallback={<div>Loading...</div>}><div className='App'><Todo /></div></React.Suspense></ErrorBoundary></RecoilRoot>);
}export default App;

2.context状态管理:

useProvider文件:

import { createContext, useContext } from "react";// 将业务逻辑拆分到一个单独文件中,方便进行状态管理
export interface StateProps {id: number;text: string;isFinished: boolean;
}
export interface ActionProps {type: string;[key: string]: any;
}
export const reducer = (state: StateProps[], action: ActionProps) => {console.log(state, action)switch (action.type) {case 'ADD':return [...state, action.todo];case 'CHANGESTATUS':return state.map(item => {if (item.id === action.id) {return Object.assign({}, item, { isFinished: !item.isFinished })}return item;});default:return state;}
}export interface ContextProps {state: StateProps[];dispatch: React.Dispatch<ActionProps>;
}
// const MyContext = createContext<ContextProps | null>(null); // 泛型写法
export const MyContext = createContext({} as ContextProps); // 断言写法export const useProvider = () => {// 改变todoconst context = useContext(MyContext);const changeTodo = (id: number) => {context.dispatch({ type: 'CHANGESTATUS', id: id });}// 添加todoconst addTodo = (todo: StateProps) => {context.dispatch({ type: 'ADD', todo });}return { changeTodo, addTodo, todoList: context.state, context };
}

ContextProvider文件:

import { useContext, useReducer } from "react";
import { MyContext, StateProps, reducer } from "./useProvider";const ContextProvider = (props: React.PropsWithChildren<{}>) => {const context = useContext(MyContext);const initState: StateProps[] = context.state || [];const [state, dispatch] = useReducer(reducer, initState);return (<MyContext.Provider value={{ state, dispatch }} >{/* 插槽内容 */}{props.children}</MyContext.Provider>)
}export default ContextProvider;

Todo组件:

import ContextProvider from "./ContextProvider";
import { TodoInput } from "./TodoInput";
import { TodoList } from "./TodoList";// 父组件
export const Todo = () => {return (<ContextProvider><TodoInput /><TodoList  /></ContextProvider>)
}

TodoInput 和TodoList 组件不变

使用Todo组件直接使用<Todo />就行;

效果图如下:

点击添加按钮,新增一列,点击多选框(选中)中划线一行,取消选中该行就恢复正常

http://www.lryc.cn/news/174198.html

相关文章:

  • 【Git】轻松学会 Git:深入理解 Git 的基本操作
  • 什么是HTTP头部(HTTP headers)?
  • SpringCloud Alibaba 入门到精通 - Sentinel
  • 【深度学习实验】前馈神经网络(三):自定义多层感知机(激活函数logistic、线性层算Linear)
  • HJ68 成绩排序
  • FPGA——UART串口通信
  • 华为云Stack的学习(七)
  • 安装k8s集群
  • C++中编写没有参数和返回值的函数
  • SWC 流程
  • 怒刷LeetCode的第10天(Java版)
  • java框架-Springboot3-场景整合
  • 在Bat To Exe Converter,修改为当异常结束或终止时,程序重新启动执行
  • PythonWeb服务器(HTTP协议)
  • Northstar 量化平台
  • c语言进阶部分详解(经典回调函数qsort()详解及模拟实现)
  • win下 lvgl模拟器codeblocks配置
  • Quartus出租车计价器VHDL计费器
  • 浅谈单元测试:测试和自动化中的利用
  • 深度详解Java序列化
  • Linux下的网络编程——B/S模型HTTP(四)
  • Go语言入门篇
  • 基于springboot+vue的青年公寓服务平台
  • Spring-ImportSelector接口功能介绍
  • YOLOv5如何训练自己的数据集
  • 李航老师《统计学习方法》第1章阅读笔记
  • 基于微信小程序的背单词学习激励系统设计与实现(源码+lw+部署文档+讲解等)
  • VScode调试复杂C/C++项目
  • 【Hash表】字母异位词分组-力扣 49 题
  • 展示日志log4.properties