
在使用 react `useref` 存储数组并尝试对其进行过滤时,一个常见误区是期望 `array.prototype.filter()` 方法能原地修改数组。实际上,`filter()` 会返回一个新数组,因此必须将这个新数组显式地重新赋值给 `ref.current` 才能实现更新。同时,访问 `ref` 中数组的属性(如 `length`)时,务必通过 `ref.current.length` 进行。
useRef 是 React 提供的一个 Hook,它允许你在函数组件中存储一个可变的引用,这个引用在组件的整个生命周期中都会持续存在,并且更新它不会触发组件的重新渲染。这使得 useRef 非常适合存储那些不需要响应式更新但需要在不同渲染之间保持不变的数据,例如 DOM 元素的引用、计时器 ID,或者像本例中不直接用于渲染的数组。
当我们将一个数组存储在 useRef 中时,我们实际上是通过 ref.current 来访问和操作这个数组。例如:
let items = useRef([]); // 初始化一个空的数组引用 // ... items.current = data; // 从数据库获取数据后赋值给引用
在 JavaScript 中,Array.prototype.filter() 方法是一个非原地修改(non-mutating)方法。这意味着它不会改变原始数组,而是根据提供的回调函数创建一个包含通过测试的新数组。
考虑以下代码片段:
items.current.filter((item) => item.name !== toy);
这段代码会正确地生成一个不包含指定 toy 的新数组。然而,它并没有将这个新数组重新赋值给 items.current。因此,items.current 仍然指向原始的、未经过滤的数组。这就是为什么在 console.log(items.current) 时会发现数组内容没有变化的原因。
要正确地从 useRef 存储的数组中移除元素,你需要将 filter() 方法返回的新数组重新赋值给 items.current。
// 假设 items 是通过 useRef([]) 定义的 // toy 是要移除的元素的名称 items.current = items.current.filter((item) => item.name !== toy);
通过这种方式,items.current 现在指向了经过过滤后的新数组,从而实现了对 useRef 中数组的“更新”。
另一个常见的错误是直接尝试访问 ref 对象的属性,而不是其 current 属性所指向的值的属性。例如,在检查数组长度时:
// 错误示例:items 是一个 ref 对象,没有 length 属性
if (items.length === 0) {
  console.log('Winner');
  // ...
}items 本身是一个 RefObject 类型,它只有一个 current 属性。要获取数组的长度,你必须通过 items.current 来访问数组,然后获取其 length 属性。
// 正确示例:通过 items.current 访问数组的 length 属性
if (items.current.length === 0) {
  console.log('Winner');
  navigate('/leaderboard', { state: time });
}结合上述两点修正,原始 handleAction 函数的正确实现应如下:
function handleAction(click, toy) {
  const item = items.current.find((item) => item.name === toy);
  if (!item) {
    setFound(`Not quite, try again!`);
    return;
  }
  if (click.x > item.left && click.x < item.right) {
    if (click.y < item.bottom && click.y > item.top) {
      setFound(`Well done! You've found Sarah's ${toy}`);
      // 修正1:重新赋值过滤后的数组
      items.current = items.current.filter((i) => i.name !== toy);
      console.log(items.current);
      // 修正2:通过 items.current.length 检查数组长度
      if (items.current.length === 0) {
        console.log('Winner');
        navigate('/leaderboard', { state: time });
      }
    }
  } else {
    setFound(`Not quite, try again!`);
    return;
  }
}通过理解 useRef 的工作原理以及 JavaScript 数组方法的特性,可以有效避免在 React 应用中处理可变数据时常见的陷阱。
以上就是掌握 React useRef 中数组的过滤与更新:避免常见陷阱的详细内容,更多请关注php中文网其它相关文章!
 
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
 
                Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号