增压您的按钮:用更少的样板简化加载状态
#javascript #网络开发人员 #react #ux

作为Web开发人员,我们都知道按钮在应用程序中的重要性。无论是提交表单,触发操作还是进行API调用,按钮在推动用户交互中都起着至关重要的作用。但是,当涉及到在按钮点击中添加异步代码(例如执行API调用并等待结果)时,我们倾向于变得懒惰或忘记添加。

用户的问题

您是否曾经遇到过按钮在等待异步操作完成时遇到或不反应的情况?它发生在我们最好的人身上。在编码的热量中,很容易忘记在我们的按钮中添加必要的加载状态,使用户感到困惑和沮丧。

在本文中,我们将探索一种简单而强大的方法来增强按钮功能,特别是要简化加载状态。尽管我们将使用React作为我们的示例框架,但这些技术可以应用于任何Web开发框架。

将加载状态添加到按钮

让我们开始了解在单击按钮中添加异步,连续运行代码的典型工作流程:

  1. 用户单击按钮,启动操作。
  2. 我们将加载状态设置为true,表明按钮正在进行。
  3. 我们开始执行异步代码,例如进行API调用。
  4. 操作完成后,我们将加载状态更新为false。

但是,每当我们需要合并此功能时,我们都会发现自己编写重复的样板代码。此外,忽略加载状态可能会导致用户体验差。

简化按钮加载

要应对这些挑战并使按钮加载体验更容易处理,我们需要直观的API和更少的样板代码。

让我们看一下React中的典型按钮代码段:

import { Button } from 'Button';

const APIButton = () => {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');

  const handleClick = () => {
    setLoading(true);
    setError('');
    submitFormToBackend()
      .then(() => {
        setLoading(false);
      })
      .catch((err) => {
        setError(err);
      });
  }

  return (
    <>
      <Button
        onClick={handleClick}
        className={`${loading && 'btn-loading'} ${error && 'btn-error'}`}
        disabled={loading}
      >
        Label
      </Button>
      {error && <div>{error}</div>}
    </>
  );
}

此代码演示了一种常见模式,在处理按钮点击时,我们可以手动管理加载和错误状态。但是,这似乎是太多的样板(我很懒惰写一些额外的钥匙打击)。

用增强的组件简化按钮加载

为了使按钮加载状态更易于管理,我们可以修改按钮组件本身。目标不是使我们的按钮代码混乱,而是以仍然可以使我们的代码可读和可维护的方式进行补充。

想象将按钮视为具有禁用,忙碌和错误状态的输入字段。

让我们增强按钮组件以内部处理加载并简化我们的代码:

interface ButtonProps {
  loading?: boolean;
  disabled?: boolean;
  onClick?: (e: MouseEvent<HTMLButtonElement>) => (void | Promise<void>);
}

export const Button: FunctionComponent<ButtonProps> = (props) => {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');

  const handleClick = (e: MouseEvent<HTMLButtonElement>) => {
    const clickResult = props.onClick?.(e);

    // If our onClick returns a Promise, handle the loading states
    if (clickResult instanceof Promise) {
      setLoading(true);
      setError('');

      clickResult
        .catch((err) => {
          if (err.status === 403) {
            setError('Unauthorized');
          }
        })
        .finally(() => {
          setLoading(false);
        });
    }
  }

  const buttonClasses = classnames('btn', {
    'btn-loading': loading,
    'btn-error': !!error
  });

  let buttonEl = (
    <button
      disabled={props.disabled || loading}
      className={buttonClasses}
      role={loading ? "progressbar" : ""}
    >
      {props.children}
    </button>
  );

  if (error) {
    buttonEl = (
      <Tooltip content={error} color="danger">
        {buttonEl}
      </Tooltip>
    );
  }

  return buttonEl;
}

使用此增强的按钮组件,我们有一种更强大,更直观的方式来管理加载和错误状态。该组件在内部照顾加载状态,使我们能够专注于编写清洁剂和更简洁的代码。

实现增压按钮

现在,让我们看看我们的新和改进按钮如何简化我们的代码:

import { Button } from 'Button';

const APIButton = () => {
  const handleClick = () => {
    return submitFormToBackend()
      .catch((err) => {
        if (err.status === 403) {
          throw new Error('Unauthorized');
        }
      });
  };

  return (
    <Button onClick={handleClick}>
      Label
    </Button>
  );
}

通过简单地返回我们的handleClick函数的承诺,我们就可以轻松地合并加载和错误状态。这是一个附加的单词,可以大大简化我们的代码并改善用户体验。

控制加载和错误状态

我们构建的承诺的按钮组件使我们有效地处理不同的方案:

  1. 如果我们不想在没有承诺的情况下显示加载状态,我们可以简单地省略从处理功能的承诺返回。
  2. 如果我们要显示加载状态,但没有错误工具提示,我们可以返回诺言,但要捕获错误,以防止按钮组件捕获它们。

结论

在本文中,我们探讨了如何通过简化加载状态来增强按钮。通过增强我们的按钮组件,我们可以简化过程,减少样板代码并提供更平滑的用户体验。

让我们参与讨论:

  • 您可以通过这种方法找到任何问题吗?
  • 让我知道您最喜欢的迷你黑客,这些小黑客可以简化您的开发过程。