如何让按钮的 onClick 覆盖 as={Link} 到={}(锚标记)?

How to have button's onClick override as={Link} to={} (anchor tag)?

我的 <List.Item as={Link} to={/lists/${list.id}}> 中有一个按钮,我想将其激活,但 as={Link} 已将整个灰色 selection 转换为锚标记;这样一来,当我单击按钮时,它只是 link 将我引导至路线,而不是执行 onClick 删除功能。如何维护 onClick 删除 <DeleteButton> 的功能,但仍然允许 List.item 的其余部分(灰色部分)保留 link 功能?

Profile.js(上图中的列表组件)

import React, { useContext } from "react";
import { useQuery } from "@apollo/react-hooks";
import { List, Image } from "semantic-ui-react";
import { Link } from "react-router-dom";

import ListForm from "../components/ListForm";
import DeleteButton from "../components/DeleteButton";
import { AuthContext } from "../context/auth";
// import ListForm from "../components/ListForm";
import { FETCH_LISTS_QUERY } from "../util/graphql";
import "../RankList.css";

function Profile(props) {
  const { user } = useContext(AuthContext);

  let lists = "";
  const { loading, data, error } = useQuery(FETCH_LISTS_QUERY);

  console.log(error);
  console.log(`Loading: ${loading}`);
  console.log(data);

  if (data) {
    lists = { data: data.getLists.filter((l) => l.username === user.username) };
    console.log(lists);
  }

  // function deleteListCallback() {
  //   props.history.push("/");
  // }

  return (
    <List selection verticalAlign="middle">
      {user && <ListForm />}
      {lists.data &&
        lists.data.map((list) => (
          <List.Item as={Link} to={`/lists/${list.id}`}>
            <Image avatar src="/images/avatar/small/helen.jpg" />
            <List.Content>
              <List.Header>{list.title}</List.Header>
            </List.Content>
            <DeleteButton listId={list.id} />
          </List.Item>
        ))}
    </List>
  );
}

export default Profile;

DeleteButton.js(删除上图中的按钮组件)

import React, { useState } from "react";
import gql from "graphql-tag";
import { useMutation } from "@apollo/react-hooks";

import { Button, Confirm, Icon } from "semantic-ui-react";

import { FETCH_LISTS_QUERY } from "../util/graphql";
import MyPopup from "../util/MyPopup";

function DeleteButton({ listId, listItemId, commentId, callback }) {
  const [confirmOpen, setConfirmOpen] = useState(false);

  let mutation;

  if (listItemId) {
    mutation = DELETE_LIST_ITEM_MUTATION
  } else if (commentId) {
    mutation = DELETE_COMMENT_MUTATION
  } else {
    mutation = DELETE_LIST_MUTATION
  }

  // const mutation = commentId ? DELETE_COMMENT_MUTATION : DELETE_LIST_MUTATION;

  const [deleteListOrComment] = useMutation(mutation, {
    update(proxy) {
      setConfirmOpen(false);
      // remove list from cache
      if (!commentId && !listItemId) {
        const data = proxy.readQuery({
          query: FETCH_LISTS_QUERY,
        });
        const resLists = data.getLists.filter((p) => p.id !== listId);
        proxy.writeQuery({
          query: FETCH_LISTS_QUERY,
          data: { getLists: [...resLists] },
        });
      }

      if (callback) callback();
    },
    variables: {
      listId,
      commentId,
    },
    onError(err) {
      console.log(err.graphQLErrors[0].extensions.exception.errors);
    },
  });

  return (
    <>
      <MyPopup content={commentId ? "Delete comment" : "Delete list"}>
        <Button
          as="div"
          color="red"
          floated="right"
          onClick={() => setConfirmOpen(true)}
        >
          <Icon name="trash" style={{ margin: 0 }} />
        </Button>
      </MyPopup>
      <Confirm
        open={confirmOpen}
        onCancel={() => setConfirmOpen(false)}
        onConfirm={deleteListOrComment}
      />
    </>
  );
}

const DELETE_LIST_MUTATION = gql`
  mutation deleteList($listId: ID!) {
    deleteList(listId: $listId)
  }
`;

const DELETE_LIST_ITEM_MUTATION = gql`
  mutation deleteListItem($listId: ID!, $listItemId: ID!) {
    deleteListItem(listId: $listId, listItemId: $listItemId) {
      id
      comments {
        id
        username
        createdAt
        body
      }
      commentCount
    }
  }
`;

const DELETE_COMMENT_MUTATION = gql`
  mutation deleteComment($listId: ID!, $commentId: ID!) {
    deleteComment(listId: $listId, commentId: $commentId) {
      id
      comments {
        id
        username
        createdAt
        body
      }
      commentCount
    }
  }
`;
export default DeleteButton;

一种解决方案是创建自定义 link 组件并使用历史对象的 push 方法进行重定向。使用此方法,您可以将引用添加到 DeleteButton 并检查事件目标是否不是 DeleteButton 组件,然后重定向。我认为这不是最干净的解决方案,我做了一点 sandbox

您可以向传递给按钮的 onClick 处理程序的事件添加 preventDefualt(如有必要,可能添加 stopPropagation)。

<Button
  as="div"
  color="red"
  floated="right"
  onClick={e => {
    e.preventDefualt();
    setConfirmOpen(true);
  }}
>