Code Monkey home page Code Monkey logo

Comments (3)

resetsix avatar resetsix commented on May 25, 2024 2

@CoderSerio 在React中使用防抖(debounce)函数时,可能会遇到一个常见的问题:组件的props或state更新导致组件重新渲染,而这些更新可能会导致传递给防抖函数的回调函数(fn)发生变化。如果防抖函数直接使用了这个回调函数,那么它可能会在某些时刻使用的是一个"旧"的回调版本,这可能会导致一些意外的副作用,尤其是当这个回调函数依赖于当前的props或state时。

useLatest 用来确保在使用函数时总是能够获取到该函数的最新版本。它内部通常是通过使用useRef来实现的,useRef会在整个组件的生命周期内保持引用值的不变,即使组件重新渲染。useLatest通过更新这个引用的当前值来确保无论何时调用,都是使用的最新传递给它的函数。

useDebounceFn Hook创建了一个防抖函数debounced,并使用useMemo确保这个防抖函数不会在每次渲染时都被重新创建。如果不使用useLatest,那么当fn变化时,由于useMemo依赖数组为空,debounced内部使用的将是旧的fn,不会因为fn的更新而更新。

使用useLatest的目的是确保在防抖函数实际执行的时刻,无论它是立即执行还是延迟执行,使用的都是最新的fn回调函数。这在如下情况下尤其重要:

  • 回调依赖外部状态:如果fn回调函数依赖于组件的state或props,那么确保使用最新的fn是非常重要的,这样才能确保回调执行时能够获取到最新的状态。

  • 防抖时间较长:如果设置了较长的防抖时间,那么在防抖函数实际执行前可能已经进行了多次操作,导致fn多次更新。使用useLatest可以确保无论防抖函数何时执行,都是使用最新的回调。

  • 函数组件快速重新渲染:在React函数组件中,组件的快速重新渲染可能会导致传递给防抖函数的回调频繁变化。如果不使用useLatest,那么防抖函数可能会捕获到一个过时的回调函数版本,导致执行的逻辑不是最新的。

长话短说,useLatest的使用是为了在React组件中使用防抖(或节流)函数时,确保无论何时函数执行,都能够访问到最新的回调函数,以避免因为闭包导致的陈旧数据问题。

from ahooks-analysis.

GpingFeng avatar GpingFeng commented on May 25, 2024

我理解这里是问 useLastest 的背景?它是用来解决 React 的闭包问题的,你可以看我这篇

https://gpingfeng.github.io/ahooks-analysis/guide/blog/closure

from ahooks-analysis.

CoderSerio avatar CoderSerio commented on May 25, 2024

不是的,这里是想了解useDebounceFn的源码:

const useDebounceFn = (fn, options) => {
  // 这是源码本来的实现,保证了传入的回调始终是最新的:
  // const fnRef = useLatest(fn);
  const wait = options?.wait ?? 1000;
  const debounced = useMemo(() => {
    return debounce(
      (...args) => {
        // return fnRef.current(...args);
        return fn(...args);
      },
      wait,
      options,
    );
  }, []);
​
  useUnmount(() => {
    debounced.cancel(); 
  });
​
  return {
    run: debounced, 
    cancel: debounced.cancel, 
    flush: debounced.flush, 
  };
};

这里是使用了useLatest的,但是个人觉得这里直接用参数传过来的也行,这里使用useLatest感觉有些多余?我没太想到useDebounceFn有什么产生闭包的场景...

这是作者的一种防御性编程吗——多处理一下总没错?

from ahooks-analysis.

Related Issues (2)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.