如何在useEffect中使用setTimeout重置React钩子状态

时间:2020-12-19 18:30:13

标签: reactjs react-hooks use-effect use-state

我有一个简单的组件,可以将链接复制到剪贴板,并且想用复选标记交换链接图标。我有这样做的逻辑设置,但是在 3 秒后重置状态以将按钮重置回链接图标时遇到问题。如何正确设置我的 useEffect 和状态挂钩以设置然后重置状态以显示/隐藏选中标记的链接并再次返回?

const [copySuccess, setCopySuccess] = useState('');
const [visible, setVisible] = useState(true);
const copyToClipBoard = async copyHeader => {
try {
  await navigator.clipboard.writeText(copyHeader);
    setCopySuccess('Copied!');
  } catch (err) {
    setCopySuccess('Failed to copy!');
  }
};

<Button>
    {copySuccess ? (
       <Icon name="success" />
    ):(
     <Icon
        name="linked"
        onClick={() => copyToClipBoard(url)}
     />
    )}
</Button>

我正在尝试这样的 useEffect

useEffect(() => {
    setTimeout(() => {
      setVisible(false);
    }, 3000);
 });
  

但不确定如何使用 setVisible 状态和超时,将图标交换回链接,让用户知道他们可以再次复制它。

2 个答案:

答案 0 :(得分:0)

您可以从 copySuccess 状态导出可见状态,尝试将其添加到 useEffect dep 数组:

const [copySuccess, setCopySuccess] = useState("");
const copyToClipBoard = async (copyHeader) => {
  try {
    await navigator.clipboard.writeText(copyHeader);
    setCopySuccess("Copied!");
  } catch (err) {
    setCopySuccess("Failed to copy!");
  }
};

useEffect(() => {
  if (copySuccess !== "") {
    setTimeout(() => {
      setCopySuccess("");
    }, 3000);
  }
}, [copySuccess]);

<Button>
  {copySuccess ? (
    <Icon name="success" />
  ) : (
    <Icon name="linked" onClick={() => copyToClipBoard(url)} />
  )}
</Button>;

在代码和框示例中看到类似的逻辑:

function Component() {
  const [copyIsAvailable, setCopyIsAvailable] = useState(true);

  useEffect(() => {
    setTimeout(() => {
      setCopyIsAvailable(true);
    }, 1000);
  }, [copyIsAvailable]);

  return (
    <button onClick={() => setCopyIsAvailable(false)}>
      {copyIsAvailable ? "copy" : "copied"}
    </button>
  );
}

Edit Q-65373145-setTimeout

答案 1 :(得分:0)

我建议您更改异步函数以更新 visible
然后更改按钮标签:

<Button>
    {visible 
      ? <Icon name="success" />
      : <Icon
         name="linked"
         onClick={() => copyToClipBoard(url)}
        />
    }
</Button>