Reputation: 99
I have a button inside my <List.Item as={Link} to={/lists/${list.id}}>
which I want to activate but the as={Link}
has converted the entire greyed selection an anchor tag; this makes it so, when I click the button, it just links me to the route rather than executing onClick delete functionality. How can I maintain the onClick delete functionality of the <DeleteButton>
but still allow for the rest of the List.item (greyed section) to keep link functionality ?
Profile.js (List component in photo above)
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 (Delete button component in photo above)
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;
Upvotes: 1
Views: 1203
Reputation: 203292
You can add preventDefualt
(and possibly stopPropagation
if necessary) to the event passed to the button's onClick handler.
<Button
as="div"
color="red"
floated="right"
onClick={e => {
e.preventDefualt();
setConfirmOpen(true);
}}
>
Upvotes: 1
Reputation:
One solution could be to create a custom link component and redirect with the push method of the history object. With this method you can add a ref to your DeleteButton and check if the event target isn't the DeleteButton component, then redirect. I don't think it's the cleanest solution, I made a little sandbox
Upvotes: 0