尝试编写一个将复制字符串的反应挂钩,然后显示警报。它有效但只运行一次

Trying to write a react hook that will copy a string, then show an alert. It works but only runs once

作为我网站的一部分,我正在尝试将其添加到我有按钮的地方,用户可以点击这些按钮,它会将我的联系信息复制到剪贴板——然后显示一个警报,确认该项目已被已复制。

我正在使用 material-ui 作为快餐栏和 react-use-clipboard 来复制地址。我在下面的作品。这些按钮在复制地址方面效果很好。完美且无休止地工作。

但是,警报是主要问题。

第一个问题是应用程序第一次加载时会出现这两个警报,而我只希望它们在按下按钮时显示。

第二个问题是它们在按下按钮时确实起作用——但只是第一次。如果我单击 'copy e-mail',它会复制电子邮件并发出警报。如果我然后单击 'copy linkedin',它会复制 linkedin 地址并发出警报。如果我然后返回并再次点击复制电子邮件,它会复制电子邮件但不会发出警报。

我不明白为什么挂钩不会 运行 警报不止一次。任何建议将不胜感激。

function Contact() {

const [isCopiedEmail, setCopiedEmail] = useClipboard("myemailaddress@gmail.com");

useEffect(() => {
    setOpenEmail(true);
    console.log("Email")}, 
    [isCopiedEmail]
    )

const [isCopiedLinkedIn, setCopiedLinkedIn] = useClipboard("https://www.linkedin.com/in/mylinkedinaddress");

useEffect(() => {
    setopenLinkedIn(true);
    console.log("LinkedIn")}, 
    [isCopiedLinkedIn]
    )

function Alert(props) {
    return <MuiAlert elevation={6} variant="filled" {...props} />;
  }
  
  const useStyles = makeStyles((theme) => ({
    root: {
      width: '100%',
      '& > * + *': {
        marginTop: theme.spacing(2),
      },
    },
  }));

  const [openLinkedIn, setopenLinkedIn] = useState(false);

  const handleCloseLinkedIn = (event, reason) => {
      if (reason === 'clickaway') {
      return;
  }
  setopenLinkedIn(false);
};

  const [openEmail, setOpenEmail] = useState(false);

  const handleCloseEmail = (event, reason) => {
    if (reason === 'clickaway') {
      return;
    }
    setOpenEmail(false);
  };

return (
    <Container className="background3">
    <Row>
        </Col>
        <Col xs={12} md={4}>
                <Button variant="contained" size="large" color="secondary" onClick={setCopiedEmail}>Copy to Clipboard</Button>
        </Col>
        <Col xs={12} md={4}>
         <Button variant="contained" size="large" color="secondary" onClick={setCopiedLinkedIn}>Copy to Clipboard</Button>

        </Col>

        <Snackbar open={openLinkedIn} autoHideDuration={2000} onClose={handleCloseLinkedIn}>
        <Alert onClose={handleCloseLinkedIn} severity="success">
        My LinkedIn URL successfully copied!
        </Alert>
        </Snackbar>

        <Snackbar open={openEmail} autoHideDuration={2000} onClose={handleCloseEmail}>
        <Alert onClose={handleCloseEmail} severity="success">
        My e-mail address successfully copied!
        </Alert>
        </Snackbar>
        
    </Row>
    </Container>
)
}

export default Contact

由于这些影响,您的应用加载时会出现警告:

  useEffect(() => {
    setOpenEmail(true);
    console.log("Email");
  }, [isCopiedEmail]);

我关注 isCopiedEmail,但同样适用于 isCopiedLinkedIn。这 运行s 当组件挂载时,无论 isCopiedEmail 的值是什么。而且,您永远不会重置 isCopiedEmail 的值,因此效果在变为 true.

后永远不会再 运行

因为你在调用 setCopiedEmail 时已经调用了一个函数,所以我会同时调用 setOpenEmail(true),并完全消除这些影响:

function Contact() {
  const [isCopiedEmail, setCopiedEmail] = useClipboard(
    "myemailaddress@gmail.com"
  );

  const [openEmail, setOpenEmail] = useState(false);
  const handleCloseEmail = (event, reason) => {
    if (reason === "clickaway") {
      return;
    }
    setOpenEmail(false);
  };

  const handleCopiedEmail = () => {
    setCopiedEmail();
    setOpenEmail(true);
  };

  // ...

  return (
    <Container className="background3">
      <Row>
        <Col xs={12} md={4}>
          <Button
            variant="contained"
            size="large"
            color="secondary"
            onClick={handleCopiedEmail}
          >
            Copy to Clipboard
          </Button>
        </Col>
        {/* ... */}
      </Row>
    </Container>
  );
}