You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React组件使用react-copy-to-clipboard时setTimeout setState失效求助

问题修正方案

你的问题核心在于setTimeout的写法错误,直接执行了setCopied(false)而非将其包装成函数传递给setTimeout,导致状态立刻被设回false,完全看不到提示。另外还有几处细节可以优化,以下是修正后的代码及关键说明:

import React, { useState, useCallback, useEffect } from 'react';
import { CopyToClipboard } from 'react-copy-to-clipboard';
import styled from 'styled-components';

const ClipBoard = () => {
  const [copied, setCopied] = useState(false);

  const onCopy = useCallback(() => {
    setCopied(true);
    // 正确写法:传递函数给setTimeout,2秒后执行状态更新
    setTimeout(() => setCopied(false), 2000);
  }, [setCopied]); // setCopied由React保证引用稳定,无需依赖copied

  // 可选:监听copied状态变化来打印日志,替代直接在onCopy里console.log
  useEffect(() => {
    console.log('copied状态:', copied);
  }, [copied]);

  return (
    <div className="app">
      <section className="section">
        {copied && <div><p>Copied</p></div>} {/* 简化条件判断写法 */}
        <CopyToClipboard onCopy={onCopy} text="Text I want to copy">
          <button type="button">
            <span className="sr-only">
              E-mail
            </span>
            Text I want to copy
          </button>
        </CopyToClipboard>
      </section>
    </div>
  );
}

export default ClipBoard;

关键改动说明

  • 修正setTimeout用法:原代码setTimeout(setCopied(false), 2000)会立即执行setCopied(false),并把执行结果(undefined)传给setTimeout,相当于没有延迟。改成() => setCopied(false)后,才会在2秒后调用状态更新函数。
  • 优化useCallback依赖:onCopy仅用到setCopied,React会保证setCopied的引用在组件生命周期内稳定,因此依赖数组只需[setCopied],无需加入copied,避免不必要的回调重新创建。
  • 状态更新的异步性处理:原代码中的console.log(copied)会打印旧状态值,因为React状态更新是异步批量处理的。若需跟踪状态变化,使用useEffect监听copied是更可靠的方式。
  • 简化条件渲染:{copied ? <div>...</div> : null}可简化为{copied && <div>...</div>},效果一致且代码更简洁。

内容的提问来源于stack exchange,提问作者Elin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 20:45:31