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>
  );
}
相关文章
|
27天前
|
设计模式 存储 前端开发
React开发设计模式及原则概念问题之自定义Hooks的作用是什么,自定义Hooks设计时要遵循什么原则呢
React开发设计模式及原则概念问题之自定义Hooks的作用是什么,自定义Hooks设计时要遵循什么原则呢
|
13天前
|
JavaScript 前端开发 安全
[译] 使用 TypeScript 开发 React Hooks
[译] 使用 TypeScript 开发 React Hooks
|
15天前
|
前端开发 JavaScript API
React Hooks 的使用场景有哪些?
【8月更文挑战第25天】
29 2
|
15天前
|
存储 前端开发 JavaScript
React Hooks的魔法:如何在组件世界里施展响应式与复用的魔法
【8月更文挑战第27天】React Hooks 是自 React 16.8 起新增的功能,支持开发者在无需类组件的情况下利用 React 的状态管理和特性。本文通过实例展示了多种核心 Hooks 的使用方法:`useState` 用于实现响应式状态管理;`useEffect` 处理副作用操作,如数据获取等;`useMemo` 和 `useCallback` 有助于性能优化;`useRef` 则提供对 DOM 的直接引用。
26 2
|
21天前
|
前端开发 JavaScript
react hooks深拷贝后无法保留视图状态
react hooks深拷贝后无法保留视图状态
|
22天前
|
前端开发 JavaScript API
|
11天前
|
容器 Kubernetes Docker
云原生JSF:在Kubernetes的星辰大海中,让JSF应用乘风破浪!
【8月更文挑战第31天】在本指南中,您将学会如何在Kubernetes上部署JavaServer Faces (JSF)应用,享受容器化带来的灵活性与可扩展性。文章详细介绍了从构建Docker镜像到配置Kubernetes部署全流程,涵盖Dockerfile编写、Kubernetes资源配置及应用验证。通过这些步骤,您的JSF应用将充分利用Kubernetes的优势,实现自动化管理和高效运行,开启Java Web开发的新篇章。
22 0
|
11天前
|
前端开发
【实战指南】React Hooks 详解超厉害!六个步骤带你提升 React 应用状态管理,快来探索!
【8月更文挑战第31天】React Hooks 是 React 16.8 推出的新特性,允许在函数组件中使用状态及其它功能而无需转换为类组件。通过以下六个步骤可有效提升 React 应用的状态管理:1)使用 `useState` Hook 添加状态;2)利用 `useEffect` Hook 执行副作用操作;3)在一个组件中结合多个 `useState` 管理不同状态;4)创建自定义 Hook 封装可重用逻辑;5)借助 `useContext` 访问上下文以简化数据传递;6)合理运用依赖项数组优化性能。React Hooks 为函数组件带来了更简洁的状态管理和副作用处理方式。
16 0
|
1月前
|
前端开发 开发者
彻底颠覆!React Hooks带来前端开发的革命,你准备好了吗?
【8月更文挑战第6天】在现代Web开发中,React作为顶级前端框架,以高效性能和丰富生态著称。React Hooks自16.8版本引入,赋予函数组件使用状态和生命周期的能力,使代码更简洁、模块化,易于维护。常用Hooks如`useState`、`useEffect`等简化了状态管理和副作用操作。Hooks不仅增强了组件能力,提高了代码可读性和可维护性,还在各种应用场景中展现出强大功能,尤其是在中大型项目中优化了代码结构和提升了开发效率。总之,React Hooks为前端开发注入了新活力,推动了更高效便捷的开发实践。
33 1
|
18天前
|
前端开发
使用 React Hooks 的三个主要好处
【8月更文挑战第24天】
22 0