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 />就行;
效果图如下:

点击添加按钮,新增一列,点击多选框(选中)中划线一行,取消选中该行就恢复正常
相关文章:
react的状态管理简单钩子方法
1.recoil useProvider文件: import { atom, useRecoilState } from recoil;const initState atom({key: initState,default: {state: [],}, })// 将业务逻辑拆分到一个单独文件中,方便进行状态管理 export interface StateProps {id: number;text: string;isFini…...
【Git】轻松学会 Git:深入理解 Git 的基本操作
文章目录 前言一、创建 Git 本地仓库1.1 什么是仓库1.2 创建本地仓库1.3 .git 目录结构 二、配置 Git三、认识 Git 的工作区、暂存区和版本库3.1 什么是 Git 的工作区、暂存区和版本库3.2 工作区、暂存区和版本库之间的关系 四、添加文件4.1 添加文件到暂存区和版本库中的命令4…...
什么是HTTP头部(HTTP headers)?
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 理解 HTTP 头部(HTTP Headers)⭐ HTTP 头部的分类⭐ HTTP 头部的应用⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦&#x…...
SpringCloud Alibaba 入门到精通 - Sentinel
SpringCloud Alibaba 入门到精通 - Sentinel 一、基础结构搭建1.父工程创建2.子工程创建 二、Sentinel的整合SpringCloud1.微服务可能存在的问题2.SpringCloud集成Sentinel搭建Dashboard3 SpringCloud 整合Sentinel 三、服务降级1 服务降级-Sentinel2 Sentinel 整合 OpenFeign3…...
【深度学习实验】前馈神经网络(三):自定义多层感知机(激活函数logistic、线性层算Linear)
目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入必要的工具包 1. 构建数据集 2. 激活函数logistic 3. 线性层算子 Linear 4. 两层的前馈神经网络MLP 5. 模型训练 一、实验介绍 本实验实现了一个简单的两层前馈神经网络 激活函数…...
HJ68 成绩排序
描述 给定一些同学的信息(名字,成绩)序列,请你将他们的信息按照成绩从高到低或从低到高的排列,相同成绩 都按先录入排列在前的规则处理。 例示: jack 70 peter 96 Tom 70 smith 67 从高到低…...
FPGA——UART串口通信
文章目录 前言一、UART通信协议1.1 通信格式2.2 MSB或LSB2.3 奇偶校验位2.4 UART传输速率 二、UART通信回环2.1 系统架构设计2.2 fsm_key2.3 baud2.4 sel_seg2.5 fifo2.6 uart_rx2.7 uart_tx2.8 top_uart2.9 发送模块时序分析2.10 接收模块的时序分析2.11 FIFO控制模块时序分析…...
华为云Stack的学习(七)
八、华为云Stack存储服务介绍 1.云硬盘EVS 云硬盘(Elastic Volume Service,EVS),又名磁盘,是一种虚拟块存储服务,主要为ECS(Elastic Cloud Server)和BMS(Bare Metal Se…...
安装k8s集群
一、前置环境配置 安装两台centos 实验环境,一台pc配有docker环境,有两个centsos7容器,其中一个容器作为master,一个作为node。如果master与node都是用默认端口,会存在冲突,所以在此基础上做细微的调整。…...
C++中编写没有参数和返回值的函数
C中编写没有参数和返回值的函数 返回值为 void 函数不需要将值返回给调用者。为了告诉编译器函数不返回值,返回类型为 void。例如: #include <iostream>// void means the function does not return a value to the caller void printHi() {std…...
SWC 流程
一个arxml 存储SWC (可以存多个,也可以一个arxml存一个SWC)一个arxml 存储 composition (只能存一个)一个arxml 存储 system description (通过import dbc自动生成system) 存储SWC和composition的arxml文件分开&#…...
怒刷LeetCode的第10天(Java版)
目录 第一题 题目来源 题目内容 解决方法 方法一:两次拓扑排序 第二题 题目来源 题目内容 解决方法 方法一:分治法 方法二:优先队列(Priority Queue) 方法三:迭代 第三题 题目来源 题目内容…...
java框架-Springboot3-场景整合
文章目录 java框架-Springboot3-场景整合批量安装中间件NoSQL整合步骤RedisTemplate定制化 接口文档远程调用WebClientHttp Interface 消息服务 java框架-Springboot3-场景整合 批量安装中间件 linux安装中间件视频 NoSQL 整合redis视频 整合步骤 RedisTemplate定制化 Re…...
在Bat To Exe Converter,修改为当异常结束或终止时,程序重新启动执行
在Bat To Exe Converter,修改为当异常结束或终止时,程序重新启动执行 .bat中的代码部分: .bat中的代码echo offpython E:\python\yoloProjectTestSmallLarge\detect.pypause,我想你能帮在Bat To Exe Converter,修改成…...
PythonWeb服务器(HTTP协议)
一、HTTP协议与实现原理 HTTP(Hypertext Transfer Protocol,超文本传输协议)是一种用于在网络上传输超文本数据的协议。它是Web应用程序通信的基础,通过客户端和服务器之间的请求和响应来传输数据。在HTTP协议中连接客户与服务器的…...
Northstar 量化平台
基于 B/S 架构、可替代付费商业软件的一站式量化交易平台。具备历史回放、策略研发、模拟交易、实盘交易等功能。兼顾全自动与半自动的使用场景。 已对接国内期货股票、外盘美股港股。 面向程序员的量化交易软件,用于期货、股票、外汇、炒币等多种交易场景ÿ…...
c语言进阶部分详解(经典回调函数qsort()详解及模拟实现)
大家好!上篇文章(c语言进阶部分详解(指针进阶2)_总之就是非常唔姆的博客-CSDN博客)我已经对回调函数进行了初步的讲解和一个简单的使用事例,鉴于篇幅有限没有进行更加详细的解释,今天便来补上。…...
win下 lvgl模拟器codeblocks配置
链接: 官方lvgl的codeblocks官方例子 下载慢的话,可能需要点工具。 需要下载的东西 https://github.com/lvgl/lv_port_win_codeblocks https://github.com/lvgl/lv_drivers/tree/4f98fddd2522b2bd661aeec3ba0caede0e56f96b https://github.com/lvgl/lvgl/tree/7a23…...
Quartus出租车计价器VHDL计费器
名称:出租车计价器VHDL计费器 软件:Quartus 语言:VHDL 要求: 启动键start表示汽车启动,起步价7元,同时路程开始计数,停止键stop表示熄火,车费和路程均为0,当暂停键pa…...
浅谈单元测试:测试和自动化中的利用
【软件测试面试突击班】如何逼自己一周刷完软件测试八股文教程,刷完面试就稳了,你也可以当高薪软件测试工程师(自动化测试) 浅谈单元测试是一件棘手的事情。我很确定测试人员在某个时候会抱怨开发人员没有正确地进行单元测试&…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
