如何将重定向 link 添加到 onclick Material ui 图标 - React

How to add redirect link to onclick Material ui icon - React

我在第 232 行向 VideocamOutlinedIcon 添加函数时遇到一些问题,我想在其中添加一个 onclick 将用户重定向到外部域 link另一个选项卡。我尝试了很多解决方案,但其中 none 有效。我尝试通过 react-router-domredirect 使用 Link,但这些都不起作用。

我的代码:

import React, { useEffect, useState, useRef } from "react";
import { Avatar, IconButton } from "@material-ui/core";
import VideocamOutlinedIcon from '@material-ui/icons/VideocamOutlined';
import MoreVertIcon from "@material-ui/icons/MoreVert";
import SearchOutlined from "@material-ui/icons/SearchOutlined";
import InsertEmoticonIcon from "@material-ui/icons/InsertEmoticon";
import MicIcon from "@material-ui/icons/Mic";
import ArrowBackIcon from "@material-ui/icons/ArrowBack";
import db from "./firebase";
import firebase from "firebase";
import "./Chat.css";
import { Link, useParams, Redirect } from "react-router-dom";
import { useStateValue } from "./StateProvider";
import { actionTypes } from "./reducer";
import UseWindowDimensions from "./UseWindowDimensions";
import useSound from "use-sound";
import "emoji-mart/css/emoji-mart.css";
import { Picker } from "emoji-mart";
import Linkify from "react-linkify";

function Chat() {
  const [seed, setSeed] = useState("");
  const [input, setInput] = useState("");
  const { roomId } = useParams();
  const [roomName, setRoomName] = useState("false");
  const [messages, setMessages] = useState([]);
  const [toggler, setToggler] = useState(true);
  const displayName = localStorage.getItem("displayName");
  const [{ togglerState }, dispatch] = useStateValue();
  const [{ photoURL }] = useStateValue();
  const [emoji, setEmoji] = useState(false);
  const [issendChecked, setIssendChecked] = useState(false);
  const [datewise, setDateWise] = useState([]);
  const [clientGMT, setClinetGMT] = useState("");
  const [lastseenPhoto, setLastseen] = useState("");
  const { width } = UseWindowDimensions();
  var hour = 0,
    extramin = 0,
    minutes = 0,
    hourly = 0,
    GMTminutes = String(clientGMT).slice(4, 6),
    scrl,
    fix = 0;

  const [playOn] = useSound(`${process.env.PUBLIC_URL}/send.mp3`, {
    volume: 0.5,
  });
  const [playOff] = useSound(`${process.env.PUBLIC_URL}/send.mp3`, {
    volume: 0.5,
  });

  const addEmoji = (e) => {
    let emoji = e.native;
    setInput(input + emoji);
  };
  const checkEmojiClose = () => {
    if (emoji) {
      setEmoji(false);
    }
  };

  function getTimeZone() {
    var offset = new Date().getTimezoneOffset(),
      o = Math.abs(offset);
    return (
      (offset < 0 ? "+" : "-") +
      ("00" + Math.floor(o / 60)).slice(-2) +
      ":" +
      ("00" + (o % 60)).slice(-2)
    );
  }
  useEffect(() => {
    setClinetGMT(getTimeZone());
  });
  useEffect(() => {
    setSeed(Math.floor(Math.random() * 5000));
    if (roomId) {
      db.collection("rooms")
        .doc(roomId)
        .onSnapshot((snapshot) => {
          setRoomName(snapshot.data().name);
        });

      db.collection("rooms")
        .doc(roomId)
        .collection("messages")
        .orderBy("timestamp", "asc")
        .onSnapshot((snapshot) => {
          setMessages(snapshot.docs.map((doc) => doc.data()));
        });
    }
  }, [roomId]);
  useEffect(() => {
    setLastseen(messages[messages.length - 1]?.photoURL);
  }, [messages]);

  const sendMessage = (e) => {
    e.preventDefault();
    if (input.length > 0) {
      db.collection("rooms")
        .doc(roomId)
        .collection("messages")
        .add({
          message: input,
          name: displayName,
          timestamp: firebase.firestore.FieldValue.serverTimestamp(),
          photoURL: localStorage.getItem("photoURL"),
        });
      setIssendChecked(!issendChecked);
      issendChecked ? playOff() : playOn();
      setInput("");
    }
  };

  let blankObj = {};
  let TotalObj = [];
  if (messages.length > 0) {
    let checkDate = "";
    let blankArray = [];
    let dateArray = [];
    messages.forEach(function (message, i) {
      let messageDate = String(
        new Date(message.timestamp?.toDate()).toUTCString()
      ).slice(5, 12);
      if (dateArray.indexOf(messageDate) === -1) {
        dateArray.push(messageDate);
      }
    });
    var index = 0;
    messages.forEach(function (message, i) {
      let messageDate = String(
        new Date(message.timestamp?.toDate()).toUTCString()
      ).slice(5, 12);
      if (messageDate === dateArray[index] && i == messages.length - 1) {
        blankArray.push({
          messageData: message.message,
          name: message.name,
          timestamp: message.timestamp,
        });
        blankObj[dateArray[index]] = blankArray;
        TotalObj.push(blankObj);
        blankObj = {};
        blankArray = [];
        blankArray.push({
          messageData: message.message,
          name: message.name,
          timestamp: message.timestamp,
        });
        index = index + 1;
      } else if (messageDate == dateArray[index]) {
        blankArray.push({
          messageData: message.message,
          name: message.name,
          timestamp: message.timestamp,
        });
      } else {
        blankObj[dateArray[index]] = blankArray;
        TotalObj.push(blankObj);
        blankObj = {};
        blankArray = [];
        blankArray.push({
          messageData: message.message,
          name: message.name,
          timestamp: message.timestamp,
        });
        if (messageDate != dateArray[index] && i == messages.length - 1) {
          blankObj[messageDate] = blankArray;
          TotalObj.push(blankObj);
        }
        index = index + 1;
      }
    });
  }
  useEffect(() => {
    setDateWise(TotalObj);
  }, [messages]);

  const messagesEndRef = useRef(null);
  const scrollToBottom = () => {
    if (messagesEndRef.current) {
      messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
    }
  };
  useEffect(() => {
    scrollToBottom();
  });

  useEffect(() => {
    setToggler(!toggler);
  }, [togglerState]);

  useEffect(() => {
    scrollToBottom();
  }, [messages]);
  const handleDrawerToggle = () => {
    setToggler(!toggler);
    dispatch({
      type: actionTypes.SET_TOGGLER,
      togglerState: togglerState + 1,
    });
  };
  return (
    <>
      {width < 629 ? (
        <div className={togglerState % 2 === 0 ? "chat" : "chat hide__chat"}>
          <div className="chat__header">
            <IconButton
              color="inherit"
              aria-label="open drawer"
              edge="start"
              onClick={handleDrawerToggle}
            >
              <ArrowBackIcon />
            </IconButton>
            <Avatar src={lastseenPhoto} />
            <div className="chat__headerInfo">
              <h3>{roomName}</h3>
              <p className="header__lastSeen">
                last seen{" "}
                {messages.length !== 0
                  ? messages[messages.length - 1].timestamp
                      ?.toDate()
                      .toUTCString()
                  : "Loading"}
              </p>
            </div>
            <div className="chat__headerRight">
              <IconButton>
                <SearchOutlined />
              </IconButton>
              <IconButton>
                <VideocamOutlinedIcon />
              </IconButton>
              <IconButton>
                <MoreVertIcon />
              </IconButton>
            </div>
          </div>

export default Chat;

尝试

onClick={() => window.open('https://whosebug.com/')}

如果是外部 link,则不需要使用 react-router-dom。只需使用浏览器的功能 window.openwindow.location.replace.

在您的情况下,在新标签页中打开:

window.open('https://www.google.com', '_blank');

那就是:

<IconButton>
  <VideocamOutlinedIcon onClick={() => window.open('https://www.google.com', '_blank')} />
</IconButton>

不确定为什么其他人推荐 onClick 处理程序,以及为什么他们将处理程序添加到图标而不是包装 IconButton。这不是正确的解决方案,只会给使用辅助技术的用户带来问题。

当你说你“想要添加一个 onclick 将用户重定向到另一个选项卡中的外部域 link”,你描述一个link。所以,当您尝试使用 react-router-domLink 时,您已经非常接近了。但是,如果您想让它尽可能简单且易于访问,您可以使用 a 元素和 target="_blank".

幸运的是,如果您在 Material UI 的 IconButton 组件上添加 href 属性,它会将其呈现为 a 元素,而不是button,因此您可以使用以下内容:

<IconButton href="https://google.com" target="_blank" rel="noopener noreferrer">
  <VideocamOutlinedIcon />
</IconButton>

它会呈现一个看起来像按钮的 link,辅助技术会将其宣布为 link。双赢.

<a
  class="MuiButtonBase-root MuiIconButton-root"
  tabindex="0"
  aria-disabled="false"
  href="https://google.com"
  target="_blank"
  rel="noopener noreferrer"
  ><span class="MuiIconButton-label"
    ><svg
      class="MuiSvgIcon-root"
      focusable="false"
      viewBox="0 0 24 24"
      aria-hidden="true"
    >
      <path
        d="M15 8v8H5V8h10m1-2H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4V7c0-.55-.45-1-1-1z"
      ></path></svg></span
  ><span class="MuiTouchRipple-root"></span
></a>