在函数式组件中管理状态:在引入 useState 之前,React 中的函数式组件没有一种有效的方式来管理内部状态。useState 解决了这个问题,允许函数式组件维护和更新它们自己的状态。...初始化状态:useState 函数的第二个参数是状态的初始值。这定义了状态变量的初始值,仅在组件的初始渲染中使用。...动态更新状态:调用 setState 函数时,React 会安排重新渲染组件,使用新的状态。这允许根据事件(例如点击、表单输入等)动态更新用户界面。...React 中,useState 对于在函数式组件中管理状态至关重要。...允许组件对状态变化作出反应并有效地更新用户界面。其简单的语法和关键角色使其成为 React 开发中不可或缺的工具。我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!
、表单数据、滚动位置...全部丢失 痛点: ❌ 状态彻底丢失 (useState被清空) ❌ 表单数据重置 (用户输入白填) ❌ 滚动位置归零 (长列表体验极差) ❌ 动画状态丢失 (CSS动画重新播放...// (重新发起请求) 实战场景: 5个真实案例 场景1: 侧边栏状态保留 业务需求: 用户在侧边栏筛选表单中填写了大量条件,关闭侧边栏后再打开,需要保留筛选条件。...业务需求: 一个复杂的表单Modal,用户填到一半点了"取消",下次打开希望保留之前的草稿。...再次点击"编辑资料" → Modal打开 ✅ 表单数据恢复到50%的状态 ✅ 用户可以继续编辑 ✅ 无需任何额外的状态管理代码 场景4: 虚拟列表的预加载优化 高级场景: 在字节飞书文档中...用户几乎感知不到延迟 ✅ 场景5: 实时数据订阅的资源管理 真实场景: 在阿里云控制台,服务器监控面板需要WebSocket实时推送数据,切换到其他Tab时需要暂停订阅。
在函数组件中调用useState来向它添加一些本地state。React将在重新渲染之间保留此状态。useState返回一对值:当前 state 值和一个用于更新这个值的函数。...详细解释 你可以在专属页上了解有关State Hook的更多信息:使用State Hook。 Effect Hook 你之前可能从React组件执行过数据获取、订阅或手动更改DOM。...例如,一个组件使用 effect来订阅朋友的在线状态,并通过取消订阅来清理它: import { useState, useEffect } from 'react'; function FriendStatus...在本页前面,我们介绍了一个调用useState和useEffect Hooks的FriendStatus组件来订阅朋友的在线状态。我们希望在另一个组件中复用此订阅逻辑。...useSomething命名约定是为了让linter插件在使用Hooks的代码中查找错误。 自定义Hook应用广泛,如表单处理、动画、声明订阅、计时器,以及可能还有更多我们没有考虑到的。
定义状态结构 2. 定义动作 2. 视图 1. 订阅状态 2. 触发动作 这是很简单的一种渲染模式,可以适用于所有的场景(暂且忽略性能之类的情况)。...对元数据的初步认知 以上的例子仍然太过简单了,我们逐步去看一些更加复杂的,比如表格和表单的状态结构: 表格: const Table = () => { // 表头信息 // 行记录信息 };...表单: const Form = () => { // 字段信息 // 字段值信息 }; 如果是按照之前的理念来实现,我们当然也可以把这些信息全部糅合到状态里,类似这样: const Foo...这样,我们之前碰到的表格表单,或者类似的形态,就有了比较统一的抽象方式了。...在之前的示例中,已经简单看到一些了。 在软件架构中,一个很重要的过程是在抽象的基础上合并同类项。
这实际上是一个很棘手的问题,因为 SSR 第一次渲染无法访问你浏览器上的 localStorage;它不可能知道初始值应该是什么。 在服务端渲染的应用中,动态内容是一个复杂的课题。...实战 这个钩子函数做了一个单一的假设,这在 React 应用程序中是相当安全的:表单输入值保存在 React 的状态(state)中。...这里有个表单非固定值的实现,控制不同值之间切换: const CalendarView = () => { const [mode, setMode] = React.useState('day')...它怎么工作 基本上,useStickyState 这个钩子函数是 useState 的包装器。只是,它做了一些其他事。 延迟初始化 首先,它发挥了延迟初始化的优势。...这使得我们可以给 useState 传递一个函数,而不是一个值。当状态 state 被创建时,这个函数只是在组件第一次渲染被执行。
很多同学(包括当时的我)第一反应是:加useMemo不就行了?...(取消订阅) 从React思维到Observable思维 React思维(传统做法): "我有一个状态,当状态变化时,组件会重新渲染。...] = useState(1); const [hasMore, setHasMore] = useState(true); // 要管理5个状态,逻辑混在一起 useEffect(() => {.../useEffect 只在必要的地方订阅Observable,其他地方保持原样。...✅ 简单的表单状态管理 ✅ UI展开/收起等本地状态 ✅ 小型项目(< 20个组件) ✅ 团队没有RxJS经验且学习成本高 八、写在最后 从去年重构到现在,这个数据看板项目已经稳定运行了好几个月。
基于函数的组件被称为哑(dumb)、瘦(skinny)或表示(presentational)组件,因为它们无法访问状态和生命周期函数。...这个插件能够帮助你在尝试运行应用程序之前捕获并修复 Hooks 错误。...建议先使用 useState Hook 声明状态变量,然后使用 useEffect Hook 编写订阅,接着编写与组件作业相关的其他函数。...使用 useState 的更新函数更新状态时,以前的状态会替换为新状态。...但是对于某些情况,例如构建一个简单的表单,最好将状态分组在一起,以便更轻松地处理更改和提交数据。 简而言之,你需要在多个 useState 调用和单个 useState 调用之间保持平衡。
当然,无论是通过 props 还是通过 state 只要保证表单组件的 value 接受的是一个非 undefined 的状态值,那么该表单元素就可以被称为受控(表单中的值是通过组件状态控制渲染的)。...之后当用户在页面上的 input 元素中输入任何值表单值都会跟随用户输入而实时变化而并不受任何组件状态的控制,这就被称为非受控组件。...在开始阅读它的代码之前,我会一步一步带你了解它的运作方式。 作用 首先,我们先来看看 useMergedState 这个 Hook 的作用。...但是由于组件内部 useState 的值已经进行过初始化了,并不会由于组件的 props 改变而重新初始化组件内部的 state 状态。 // ......postState(chosenValue) : chosenValue; // ... } 上述的这段初始化逻辑其实和我们刚才差不多,对于传入的参数在内部使用 useState 进行初始化。
通过在函数组件中调用useState,就会创建一个单独的状态。 在类组件中,state 总是一个对象,可以在该对象上添加保存属性。...显示的内容 // maxLength - 在点击“read more”之前显示多少个字符 function LessText({ text, maxLength }) { // 创建一个状态,并将其初始化为...示例:根据之前的状态更新状态 看看另一个例子:根据前一个值更新state的值。 咱们要造个计步器,每点击一次按钮,就计一次,点击完后,它会告诉你你走了多少步。...这与this.setState在类中的工作方式不同。 示例:具有多个键的 state 再来看看,state为对象的例子,创建一个包含2个字段的登录表单:username 和password。...首先,我们创建一个state片段,并用一个对象初始化它 const [form, setValues] = useState({ username: '', password: '' }) 这看起来像是在类中初始化状态的方式
在之前的API中,这意味着应用useMemo、useCallback和memo API来手动调整React在状态变化时重新渲染的部分。...在使用Action之前 在下面的代码片段中,我们将利用 onSubmit事件,在表单提交时触发搜索操作。...useFormStatus() hook 在 React19 中,我们还有新的 hooks 来处理表单状态和数据。这将使处理表单更加流畅和简单。...在 submitForm 中,我们正在检查表单的值。 prevState:初始状态将为 null,之后它将返回表单的 prevState。...const [messages, setMessages] = useState([{ text: "初始化信息", sending: false, key: 1 },]); 在 submitData
初始化 useState 错误 错误地初始化 useState hook 是开发人员在使用它时最常犯的错误之一。问题是 useState 允许你使用任何你想要的东西来定义它的初始状态。...然而,没有人直接告诉你的是,根据组件在该状态下的期望,使用错误的类型值初始化 useState 可能会导致应用程序中意外的行为,例如无法呈现 UI,导致黑屏错误。...,在呈现组件之前检查它是否可访问,例如 user.names && user.names.firstname,它只在左侧表达式为真(如果 user.names 存在)时计算右侧表达式。...这将在预定的更新时间将当前状态传递给回调函数,从而可以在尝试更新之前知道当前状态。 因此,让我们修改示例演示,使用函数更新而不是直接更新。...管理表单中的多个输入字段 管理表单中的几个受控输入通常是通过为每个输入字段手动创建多个 useState() 函数并将每个函数绑定到相应的输入字段来完成的。
因此,引入了 Hooks: 使用 Hooks 可以从组件中提取有状态逻辑,这样就可以独立地对其进行测试并复用。其允许在不改变组件层次结构的情况下复用有状态逻辑。...这样可以做到各个 Hook 在每一次渲染中,调用的顺序是一致的。 const [count, setCount] = useState(0); 数组结构语法允许我们为状态变量赋予不同的名称。...替代生命周期 constructor: 函数组件不需要 constructor,可以通过 useState 初始化(如果数据复杂,可以传入函数); getDerivedStateFromProps:渲染过程更新...使用 useState 声明可以直接更新的状态变量。 使用 useReducer 在 reducer 函数 中声明带有更新逻辑的 state 变量。...useLayoutEffect 在浏览器重新绘制屏幕前执行,可以在此处测量布局。 useInsertionEffect 在 React 对 DOM 进行更改之前触发,库可以在此处插入动态 CSS。
就是一个 Hooks,以前的函数组件是无状态的,但是有了 Hooks 后我们可以在函数中通过 useState 来获取 state 属性(count)以及修改 state 属性的方法(setCount...(初始化)后以及之后每次更新都需要该操作,一个是初始化一个是更新后,这种情况在平时经常会遇到,有时候遇到初始化问题,就避免不了会写两次,哪怕是抽离成单独的函数,也必须要在两个地方调用,当这种写法多了起来后将会变得冗余且容易出...可以看到无论是初始化渲染还是更新渲染,useEffect 总是会确保在组件渲染完毕后再执行,这就相当于组合了初始化和更新渲染时的生命周期钩子。...下面演示类组件是如何清除订阅的: // 一个订阅好友的在线状态的组件 class FriendStatus extends React.Component { constructor(props) ...2.2.3 实现不同逻辑分离 刚才讲的都是在一个场景下使用 Hooks 。 现在将计数组件和好友在线状态组件结合并作对比。
在 Vue 3.0 到来之前不要把 Vue Composition API 视为 100% 确定的。 React Hooks 允许你 "勾入" 诸如组件状态和副作用处理等 React 功能中。...使用 name 状态变量 const [name, setName] = useState('Mary'); // 2. 使用一个持久化表单的副作用 if (name !...使用 name 状态变量 const name = ref("Mary"); // 2. 使用一个 watcher 以持久化表单 if(name.value !...useReducer 还有一种 延迟初始化 的形式,传入一个 init 函数作为第三个参数。 Vue 则由于其天然的反应式特性,有着不同的做法。...Vue Composition API 中,如我们在几乎所有文中之前的例子中所见,ref 可被用于定义反应式状态。
实战场景:封装网络状态检测 假设你在做一个在线协作工具(类似腾讯文档),需要实时监测用户网络状态: // hooks/useOnlineStatus.js import { useState, useEffect...2025新范式: 在渲染之前就启动数据请求,配合Suspense。...模式7:受控vs非受控组件——表单性能优化的关键 场景: 一个有20个输入框的复杂表单,每次输入都卡顿。...selector(user) : user; } 使用时精准订阅: function UserName() { // 只订阅name,avatar变化不会导致re-render const name...- 别滥用全局状态 复合组件 - 写出优雅的API 预加载模式 - 消灭useEffect瀑布流 错误边界 - 线上稳定性的底线 RSC - 性能优化的新范式 受控/非受控 - 表单性能的分水岭 Context
如果你的表单有 50 个字段,用传统的 useState 逐个维护每个字段的状态,会发生什么?...现代库的解决方案:订阅模式 React Hook Form 和 Formik 都采用了一个聪明的方法:把表单状态和渲染解耦。...最核心的想法是:用 React ref 存储表单状态(不触发重新渲染),然后让每个字段只订阅它关心的状态片段。...而且一旦逻辑变复杂(比如:返回上一步改了选择,需要清空之前的字段),就容易出 bug。 方案:状态机 把表单看作一个状态机。每个步骤或分支是一个状态,字段的可见性由状态决定。...:明确的步骤转移,不会出现非法状态 ✅ 自动草稿保存:用户进度不会丢失 ✅ 分层验证:同步和异步验证分离 ✅ 错误映射:服务器错误自动回填表单 ✅ 订阅模式:只有相关组件才会重新渲染,性能高效 总结:大规模表单的建筑蓝图
在 class 中,可以通过在构造函数中设置 this.state 来初始化 state,但是在函数组件中,我们没有 this,所以不能分配或读取 this.state,我们直接在组件中调用 useState...当然,如果存在多个表单域,最好的实现方式是将 Hook 提取出复用的函数: import React, { useState } from 'react' export default function...传递给 useEffect 的函数在每次渲染中都会有所不同,这是刻意为之的。每次重新渲染,都会生成新的 effect,替换掉之前的。...当 state 逻辑较复杂且包含多个子值,或者下一个 state 依赖于之前的 state 时候,可以使用 useReducer 代替 useState。...这让 React 能够在多次的 useState 和 useEffect 调用之间保持 hook 状态的正确。 只在 React 函数中调用 Hook。
举一个想象这样一个场景, 一个页面上面同时有一个表单和一个表格,就像下图所示这样图片我们希望用户在点击查询按钮的时候, 表格可以将当前页码调整为第一页,同时加载表格的数据,比如像下面代码所示import...问题分析我们知道,在React的事件循环内部,多次setState会被合并成一次来触发更新,所以我们通常写React批量更新状态的时候并不会出现问题,但是这里有一个特例,就是React不会将异步代码里面的多次状态更新进行合并...所有异步状态都需要用unstable_batchedUpdates来包裹吗我认为是不需要的,只有在批量更新状态的时候引起请求重复发送,页面渲染卡顿等影响用户体验的时候,再用这个api也不迟发布订阅者模式...layout) { // 初始化layout layout = document.querySelector(".layout"); // addEventListener...订阅事件上面的代码实现了layout resize的发布订阅代码,那么如何在useLayoutResize中使用呢?
这在处理动画和表单的时候,尤其常见,当我们在组件中连接外部的数据源,然后希望在组件中执行更多其他的操作的时候,我们就会把组件搞得特别糟糕: 难以重用和共享组件中的与状态相关的逻辑,造成产生很多巨大的组件...我们使用React本地状态来保持当前窗口宽度,并在窗口调整大小时使用副作用来设置该状态 import { useState, useEffect} from 'react'; // custom hooks...如何实现 useState() 方法 让我们在这里通过一个例子来演示状态 hooks 的实现如何工作。...1)初始化 创建两个空数组:setters和state 将光标设置为 0 [image.png] 初始化:两个空数组,Cursor为0 2) 首次渲染 首次运行组件功能。...每次useState()调用,当在第一次运行时,将setter函数(绑定到光标位置)推送到setter数组,然后将某个状态推送到state数组。
,启动你的 React 项目 cd myapp npm start 三、类组件中的 State 状态管理 在学习 Hooks 中的状态管理之前,我们先复习下,在类组件中怎么进行状态管理的,有了对比,才能更好的理解...则是初始化 state 状态的默认值(可以通过函数的形式返回值)。...在讲解之前,小编先出一道题,看看能否答对: function A () { const [count, setCount] = useState(4); setCount(count...从上图所示,如果你使用的是函数方式的初始化状态值,每次更改状态值,只打印一次。 如果是 Object 的状态值,我们只想更改个别属性的值,为了避免出错,我们该怎么做呢?...这里我们就可以用到 Hooks 的状态值了,初始化内容为空,这里我们定义了 enteredTitle,enteredAmount 两个状态值,同时在提交按钮上绑定了一个属性方法 submitHandler