React - 节流/去抖动微调器(加载消息) - 不显示请求是不是快于 X 毫秒

Posted

技术标签:

【中文标题】React - 节流/去抖动微调器(加载消息) - 不显示请求是不是快于 X 毫秒【英文标题】:React - Throttle/debounce spinner (loading message) - not show if request is faster than X millisecondsReact - 节流/去抖动微调器(加载消息) - 不显示请求是否快于 X 毫秒 【发布时间】:2019-01-07 04:53:11 【问题描述】:

我正在我的 react 应用程序中准备微调器。

效果很好。但是,一些 UX 提示说,微调器/加载器/等应该在等待一段时间后显示。对于这个例子,假设它应该是 750 毫秒。

如何限制/去抖动(我仍然不确定有什么区别)重新渲染组件?

在上面的例子中,加载状态不应随时出现。

【问题讨论】:

嘿,这里有一个简单的演示来一劳永逸地澄清这个话题demo.nimius.net/debounce_throttle 【参考方案1】:

带有钩子和效果:

import React,  useEffect, useState  from 'react';

const DelayedSpinner = ( size ) => 
  const [showSpinner, setShowSpinner] = useState(false);

  useEffect(() => 
    const timer = setTimeout(() => setShowSpinner(true), 750);

    return () => clearTimeout(timer);
  );

  return showSpinner && <Spinner size=size color="primary" />;
;

export default DelayedSpinner;

【讨论】:

【参考方案2】:

您可以创建一个DelayedSpinner 组件,该组件在componentDidMount 中启动一个计时器,并在它经过后呈现微调器:

class DelayedSpinner extends Component 
    state = 
        showSpinner: false,
    ;

    componentDidMount() 
        this.timer = setTimeout(
            () => this.setState(showSpinner: true), 
            this.props.delay
        );
    

    componentWillUnmount() 
        clearTimeout(this.timer);
    

    render() 
        return this.state.showSpinner && <Spinner />;
    

用法:

render() 
    if (loading) return <DelayedSpinner delay=750 />

    return(
        /* render loaded data */
    );

然后您可以在启动请求后渲染该微调器,它只会在一定延迟后显示。

【讨论】:

你提出的解决问题很简单...我喜欢它! @MateuszJagieło 谢谢。我忘了包括计时器的失效,以防微调器在延迟过去之前被卸载。确保包含它,否则您将收到一个丑陋的警告,通知您它试图在未安装的组件上调用setState。我相应地更新了我的答案。 为什么要把render返回值放在括号里? @amankkg 这是通过评估 括号内的条件计算得出的值。如果您不将其包装在括号中,它将不是有效的 jsx。这与您包装像this.props.something 这样的变量的原因相同。 @trixn 但是还没有任何 JSX 标签,可以简化为return this.state.showSpinner &amp;&amp; &lt;Spinner /&gt;【参考方案3】:

你可以使用setTimeoutclearTimeout去抖动

componentDidMount() 
    let debounceTime = 100;
    let timeoutId = setTimeout(() => this.setState( loading: true ), debounceTime);
    fakeApiCall().then(() => 
      clearTimeout(timeoutId);
      this.setState(
        loading: false
      )
    );
  

一旦去抖时间过去,它会将加载设置为 true。如果请求花费的时间较短,则会在 Promise 中清除。

您可能想要添加一个新状态,如“初始化”或类似的东西;否则,如果您以 loading: false 启动应用程序(在等待去抖动器时),您最初会看到“Ok,got data”消息

此外,您可以使组件可配置并从道具中获取去抖动时间

【讨论】:

我已经有了初始化状态。示例只是示例。 :) 谢谢。

以上是关于React - 节流/去抖动微调器(加载消息) - 不显示请求是不是快于 X 毫秒的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Svelte 去抖动/节流?

节流和去抖动功能

React suspense 防止后备微调器闪烁

Vuetify:节流/去抖动 v-autocomplete

javascript 节流(不是去抖动)一种方法 - 类似于lodash,但更简单

如何创建类似于 javascript 节流/去抖动功能的 Rails/Ruby 方法