如何让按钮的 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);
}}
>
我的 <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);
}}
>