首页 > 解决方案 > 如何在事件处理程序中使用 React useState 挂钩禁用按钮

问题描述

https://codesandbox.io/s/busy-lamport-lfqwt?file=/src/App.js:0-678

使用状态挂钩

const [loading, _setLoading] = useState(false)

需要根据上面的状态禁用一个按钮

 return (
        <div className="App">
          <button type="button"
             onClick={handleSubmit}
              disabled={loading}> Send </button>
        </div>
      );

事件处理程序是

 async function handleSubmit(event) {
        setLoading(true)
        console.log(loadingRef.current)

        await setTimeout( () => {} , 3000)
        
        setLoading(false)
        console.log(loadingRef.current)
  }

在 setTimeout 等待三秒钟时,需要禁用该按钮

React 在稍后运行事件处理程序时将默认加载状态存储在闭包中。所以我使用 useRef 来访问处理程序内部的当前值(与需要实现的目标无关)如何根据加载状态禁用按钮三秒钟。

标签: reactjsreact-hooks

解决方案


您在这里有几个问题:

  1. setTimeout不会返回 Promise,因此await不会延迟执行第二次setLoading调用。
  2. 您正在传递onclick(全部小写)而不是onClickto <Button>

解决这些问题(并清除您所说的不相关的 ref 内容),您将进入这个工作示例(demo):

import React, { useState } from "react";
import "./styles.css";

export default function App() {
  const [loading, setLoading] = useState(false);

  async function handleSubmit(event) {
    setLoading(true);
    console.log(loading);

    await new Promise((resolve) =>
      setTimeout(() => {
        resolve();
      }, 3000)
    );

    setLoading(false);
    console.log(loading);
  }

  return (
    <div className="App">
      <button type="button" onClick={handleSubmit} disabled={loading}>
        Send
      </button>
    </div>
  );
}

推荐阅读