react hooks 闭包陷阱

简介: react hooks 闭包陷阱

react Hooks 陷阱

  • react 函数组件 + hook 为我们带来了,很多的方便,但同时也会遇到一些陷阱
  • hooks必须在函数顶层 ,不能在条件分支内 ,那么你踩到了那些坑 ?

1、useState 陷阱

陷阱:【异步陷阱】

function Index() {
  const [count, setCount] = useState(0);
  
  function add(){
      setCount( count + 1 );
      console.log(count);  // 0
  }
  return (
      <div>
        <span>{count}</span>
        <button @click=()=>{ add() }> + </button>
     </div>
  );
}
  • 点击添加按钮,发现值更新了,打印的值却还是上次的
  • 什么 useState 修改状态 是异步

解决方法:

  • 所以我们不能修改后,把值去拿去其他操作 (应该拿 count+1)
  • 可以通过 promise 来 .then 获取 最新 👇
new Promise((resolve) => {
    setCount((count) => {
        resolve(count + 1);
        return count + 1;
    });
}).then((res) => {
    // 下一步操作
    console.log(res)
});

陷阱:【只更新最后1个】

function Index() {
  const [count, setCount] = useState(0);
  
  function add(){
      setCount( count + 1 );
      setCount( count + 2 );
      setCount( count + 3 );
  }
  return (
      <div>
        <span>{count}</span>
        <button @click=()=>{ add() }> + </button>
     </div>
  );
}
  • 此时 只执行了 最后一个 setCount , 导致数据不是部分逻辑未执行
  • 如果出现这种 判断条件多次 操作 useState 怎么解决 👇
  function add(){
      let num = count;
      if(...) { num += 1; }
      if(...) { num += 2; }
      if(...) { num += 3; }
      setCount( num );
  }

2、useEffect 陷阱

陷阱:【过期闭包】

function Index() {
  const [count, setCount] = useState(0);
  
  useEffect(()=>{
    setInterval(() => {   console.log(`Count: ${count}`)  }, 1000);
  }, []);
 
  return (
      <div>
        <span>{count}</span>
        <button @click=()=>{ setCount(count+1) }> + </button>
     </div>
  );
}
  • 通过计时器,每 1 秒 打印下 count
  • 点击按钮,count 已增加 ,打印的值一直不变
  • 说明此时的 useEffect 中的 count ,还是取的 过期的值

解决方法:

  • 需要,添加依赖项 count ,
  • 并且每次更新,添加计时器,结束改变计时器
function Index() {
  const [count, setCount] = useState(0);
  
  useEffect(()=>{
       const time = setInterval(() => {   console.log(`Count: ${count}`)  }, 1000);
      return () => { clearInterval(time) };
  }, [count]);
 
  return (
      <div>
        <span>{count}</span>
        <button @click=()=>{ setCount(count+1) }> + </button>
     </div>
  );
}

3、useCallback 陷阱

  • useCallback 本来拿来优化性能,当依赖变化不用重新注册该函数
  • 使用不当也会,出现一定的问题

陷阱:【获取父组件的值,不是最新】

function Parent() {
  let [count, setCount] = useState(0);
  return (
    <div>
      <button onClick={() => setCount(count+1)}> +1 </button>
      // 子组件
      <Child count={count} />
    </div>
  );
}

function Child(props){
  let log = useCallback(() => {  console.log(props.count)  }, [])
  return (
    <div>
      count: {props.count}
      <button onClick={() => log()}> 打印 </button>
    </div>
  );

}
  • 此时我们在 父组件点击 增加按钮
  • 子组件的 count 发生改变 ,我们在点击打印按钮,发现count 一直是0
  • 说明useCallback 依赖为【】数组,取到count 已经过期了 ,

解决方法:

  • 方法1 :等于没有优化 (依赖更新,useCallback重写一次)
  let log = useCallback(() => {  console.log(props.count)  }, [props.count])
  • 方法2 :将获取 count 的方法 创建到父组件,子组件调用父组件方法
function Parent() {
  let [count, setCount] = useState(0);
  let log = useCallback(() => {  console.log(count)  }, [])
  return (
    <div>
      <button onClick={() => setCount(count+1)}> +1 </button>
      // 子组件
      <Child count={count} log={log} />
    </div>
  );
}

function Child(props){
  return (
    <div>
      count: {props.count}
      <button onClick={() => props.log()}> 打印 </button>
    </div>
  );
}
相关文章
|
1月前
|
前端开发 JavaScript
React Hooks 全面解析
【10月更文挑战第11天】React Hooks 是 React 16.8 引入的新特性,允许在函数组件中使用状态和其他 React 特性,简化了状态管理和生命周期管理。本文从基础概念入手,详细介绍了 `useState` 和 `useEffect` 的用法,探讨了常见问题和易错点,并提供了代码示例。通过学习本文,你将更好地理解和使用 Hooks,提升开发效率。
68 4
|
1月前
|
前端开发
深入解析React Hooks:构建高效且可维护的前端应用
本文将带你走进React Hooks的世界,探索这一革新特性如何改变我们构建React组件的方式。通过分析Hooks的核心概念、使用方法和最佳实践,文章旨在帮助你充分利用Hooks来提高开发效率,编写更简洁、更可维护的前端代码。我们将通过实际代码示例,深入了解useState、useEffect等常用Hooks的内部工作原理,并探讨如何自定义Hooks以复用逻辑。
|
12天前
|
前端开发 JavaScript
深入探索React Hooks:从useState到useEffect
深入探索React Hooks:从useState到useEffect
|
22天前
|
前端开发 JavaScript 开发者
“揭秘React Hooks的神秘面纱:如何掌握这些改变游戏规则的超能力以打造无敌前端应用”
【10月更文挑战第25天】React Hooks 自 2018 年推出以来,已成为 React 功能组件的重要组成部分。本文全面解析了 React Hooks 的核心概念,包括 `useState` 和 `useEffect` 的使用方法,并提供了最佳实践,如避免过度使用 Hooks、保持 Hooks 调用顺序一致、使用 `useReducer` 管理复杂状态逻辑、自定义 Hooks 封装复用逻辑等,帮助开发者更高效地使用 Hooks,构建健壮且易于维护的 React 应用。
29 2
|
27天前
|
前端开发 开发者
React 提供的其他重要 Hooks
【10月更文挑战第20天】React 提供了一系列强大的 Hooks,除了 `useRef` 之外,还有许多其他重要的 Hooks,它们共同构成了函数式组件开发的基础。
35 6
|
4天前
|
缓存 前端开发 开发者
深入理解React Hooks,打造高效响应式UI
深入理解React Hooks,打造高效响应式UI
13 0
|
1月前
|
前端开发 JavaScript 开发者
React Hooks
10月更文挑战第13天
34 1
|
1月前
|
前端开发
|
1月前
|
前端开发 JavaScript API
自定义React Hooks综合指南
本文介绍了React Hooks及其在组件开发中的作用,重点讲解了自定义Hook的创建和使用方法。通过实例展示了如何创建`useWindowWidth`、`useFetch`和`useForm`等自定义Hook,并分享了使用自定义Hook的最佳实践。文章强调了自定义Hook在提高代码复用性和组件可维护性方面的重要性。
57 0
|
1月前
|
存储 前端开发 JavaScript
深入理解React组件的生命周期与Hooks
【10月更文挑战第7天】深入理解React组件的生命周期与Hooks
91 0