专题:Hooks 与状态

请添加图片描述

从联系人 A 切到联系人 B,标题已经变了,输入框里却还留着 A 的备注。代码里 useState 接收了 props 的初始值,开发者因此以为 props 改变会自动重置状态。实际上,初始化只发生在对应状态实例建立时。

先理解问题

状态跟随组件在树中的身份保存。相同位置、相同类型通常继续复用原实例;key 可以明确表达业务身份变化。决定是否重建之前,先回答草稿属于哪一个实体,以及切换时应保留还是丢弃。

实现路径

  1. 把用户身份与编辑草稿区分开:联系人 ID 作为身份,草稿由编辑器持有。
  2. 需要切换实体就清空整份局部状态时,在编辑器边界设置稳定的实体 key。
  3. 需要保留多份未提交草稿时,把它们提升为按 ID 索引的字典,而不是强行重建后再找回。

核心示例

import {useState} from 'react';
import {TextInput} from 'react-native';
type Contact = {id: string; note: string};
function Editor({contact}: {contact: Contact}) {
  const [draft, setDraft] = useState(contact.note);
  return <TextInput value={draft} onChangeText={setDraft} />;
}
export function ContactForm({contact}: {contact: Contact}) {
  return <Editor key={contact.id} contact={contact} />;
}

key 放在真正拥有局部状态的 Editor 上。A 与 B 的身份不同,编辑器会重新建立;如果 A 的服务端备注在同一 ID 下刷新,这段代码不会自动覆盖正在输入的草稿,这通常是避免编辑被打断的合理起点。

容易忽略的边界

不要使用 Date.now() 或随机数当 key,那会让普通重渲染也不断销毁输入框,导致焦点和选区丢失。同一个实体收到新版本数据时,是否覆盖草稿应由明确的冲突策略决定,不能假装“重置”适用于所有更新。

怎么验证

  • A 输入未保存备注,再切 B:B 显示自己的初始内容。
  • 同一联系人触发父组件刷新:输入焦点与草稿保持。
  • 切回 A:行为必须符合产品约定的保留或丢弃策略。

key 是状态身份的声明。把边界放对,比事后用多个 Effect 修补串数据更容易验证。

适用范围与参考

示例用于说明设计与排查方法,非完整应用,也不代表已经过设备实测。 组件片段需接入对应项目;文中自定义函数、示意协议和策略数值需按业务补齐。迁移到 OHOS 时应另外核对适配层支持。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐