首页 > 解决方案 > 在 React 中的按钮的 onClick 中立即手动显示 Loading/Spinner(无需等待 setter)

问题描述

我有一种情况,我无法遵循调用 setter 的 React 标准,例如setLoading,然后检查是否在渲染上显示组件,{loading && <Loading />

我有一个提交按钮,单击该按钮应立即显示一个没有延迟的微调器,但设置器是异步的。因此我需要在onClick. 当后续渲染发生时,他们可以读取此状态并像往常一样显示/隐藏微调器,使用{loading && <Loading />.

我正在考虑使用document.getElementById('spinner').style.display = 'block' / 'none',但是这可以与显示/隐藏组件的 React 渲染一起使用吗?有没有办法在 JS 中立即强制显示 React 组件?

<Button type="submit" 
        onClick={() => { 
            // Can't use this setter because it doesn't update right away
            // setIsLoading(true);

            // Is this a good idea? Will subsequent renders read this?
            document.getElementById('spinner').style.display = 'block';
       }}

更新:没有找到好的解决方案。为了减轻 setter 启动之前的小延迟,我们使用 Formik 禁用提交按钮{isSubmitting}

<Button type="button" disabled={isSubmitting}> Submit</Button>

这至少会禁用该按钮,因此您无法再次单击它。但立即显示微调器是困难的。即使我们强制它的可见性onClick=与 React 自己的变量冲突,所以将手动方法与 React 混合并不能将其关闭。我们必须忍受这个非常小的延迟。

标签: reactjs

解决方案


在状态下为微调器添加一个属性:

state = {
  spinnerClass: 'invisible'
}

或者如果您使用的是功能组件

import React, { useState } from 'react';

// function
let [spinnerClass, updateClass] = useState('invisible');

然后设置一些CSS:

.invisible {
  display: none;
/* OR */
  visibility: hidden;
  opacity: 0;
}

然后向微调器添加一个类

<Spinner className={this.state.spinnerClass} />
/ or
<Spinner className={spinnerClass} />

和一个函数

changeClass = () => {
  this.setState({ spinnerClass: '' });
// or
  changeClass('');
}

为按钮添加 onclick

<button onClick={changeClass} />

推荐阅读