【问题标题】:How to add redirect link to onclick Material ui icon - React如何将重定向链接添加到 onclick Material ui 图标 - React
【发布时间】:2021-04-04 14:32:30
【问题描述】:

我在第 232 行向VideocamOutlinedIcon 添加函数时遇到一些问题,我想在其中添加一个onclick,将用户重定向到另一个选项卡中的外部域链接。我尝试了许多解决方案,但没有一个有效。我尝试通过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;

【问题讨论】:

    标签: javascript reactjs react-router onclick material-ui


    【解决方案1】:

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

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

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

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

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

    <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>
    
    

    【讨论】:

      【解决方案2】:

      在外部链接的情况下,您不需要使用 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>
      

      【讨论】:

        【解决方案3】:

        试试

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

        【讨论】:

        • 最好用最少的代码示例来回答,并添加有关其工作原理的解释
        猜你喜欢
        • 2021-11-17
        • 2022-11-11
        • 2020-09-27
        • 2018-10-26
        • 2023-03-07
        • 2021-09-03
        • 2017-04-05
        • 2019-10-19
        • 2021-03-24
        相关资源
        最近更新 更多