【问题标题】: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 毫秒。

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

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

【问题讨论】:

标签: javascript reactjs throttling debouncing


【解决方案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”消息

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

    【讨论】:

    • 我已经有了初始化状态。示例只是示例。 :) 谢谢。
    猜你喜欢
    • 2016-05-21
    • 2018-03-25
    • 2021-06-13
    • 1970-01-01
    • 2015-07-25
    • 2019-11-11
    • 1970-01-01
    • 2016-07-23
    • 1970-01-01
    相关资源
    最近更新 更多