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
相关产品推荐
相关产品推荐

