nextjs tanstack react query issue
Answered
Crazy ant posted this in #help-forum
Crazy antOP
I have a react tanstack table where I have listed all items and when I want to go to particular item detail, I need to click on Action as below
when I check console log of "id" in editor, every time I find that previous item's id is also logged in the console along with current item's id.
I am confused where it went wrong. I need to see only the particular item's id on which I clicked.
Editor ->
when I check console log of "id" in editor, every time I find that previous item's id is also logged in the console along with current item's id.
I am confused where it went wrong. I need to see only the particular item's id on which I clicked.
columnHelper.accessor('_id', {
cell: row => (
<div className="flex gap-4">
<Editor id={row.getValue()} />
</div>
),
header: () => <span>Action</span>,
}),
Editor ->
export default function Editor({id}) {
console.log(id)
const [open, setOpen] = useState(false)
const handleDialogChange = () => {
setOpen(!open)
}
return(
<Dialog open={open} onOpenChange={handleDialogChange}>
<DialogTrigger asChild>
<Button
variant="outline"
className="item-container>
Browse
</Button>
</DialogTrigger>
<DialogContent className="item-content">
<DialogHeader className="items-center justify-center">
<DialogTitle className="action-caption">
Item
</DialogTitle>
</DialogHeader>
.....................................................
...................................................
</DialogContent>
</Dialog >
)
}
48 Replies
Hi! If you log your state too, you might find out that previous id and open = false
Current id and open = true
Current id and open = true
Crazy antOP
@Julienng , Its true, But how to get currentId . because all other id's are also fetched. How to differentiate.Actually I dont want to use UseEffect and UseCallback since the html content is inside a dialog.
if you opened a dialog and close it
and try to open another one, you'll still have the old id
you could create a new state like
const [currentId, setCurrentId] = useState(id);
useEffect(() => {
setCurrentId(id)
}, [id]);
and it doesn't matter if there is html content inside the dialog
and one thing
I'm sure that you're using radix-ui / shadcn dialog component;
why do you've a
why do you've a
<DialogTrigger>
and also a state for open
Crazy antOP
I resolved This let me explain
Crazy antOP
I do not use useState etc because this makes a messup for me as if I need more states I have to maintain many useState's and code will be long. Inseatd if require I use useReducer. In this case I have done below tricks which saves me to write additional lines to-> Insead of normal fetch , I used tanstack query to fetch items from backend but in the useQuery I just put a condition to fech query if only dialog is opened. Actually the scenario was since I was just pushing id like below <Editor id={row.getValue()} /> all id's are automaticlly coming from data tables. So I need to fetch only the item id for which dialog is opened. So I justed use tanstack query and put a boolean condition in it.
1. You fetch the data and show the table (including the fetched data)
2. You use
2. You use
useQuery
when the your Dialog opens, to get the data based of the passed id?I would not bound the <Editor /> to every result of your table
Crazy antOP
yes
YourTable.tsx
Editor.tsx
const [openDialog, setOpenDialog] = useState(false);
/*....*/
// your cell
cell: row => (
<div className="flex gap-4">
<Button variant="outline" className="item-container" onClick={() => setOpenDialog(true)}>Browse</Button>
</div>
)
return (
<>
// TABLE ETC....
<Editor open={openDialog} onOpenChange={(value: boolean) => setOpenDialog(false)} />
</>
)
Editor.tsx
export default function Editor({id, open: passedOpen, onOpenChange}: {id: string | null, open: boolean, onOpenChange: (value: boolean) => void}) {
const [open, setOpen] = useState(false);
const handleOpenChange = (value: boolean) => {
setOpen(false);
onOpenChange(false);
}
return <Dialog open={open} onOpenChange={(value: boolean) => setEditorDialogOpen()}>
<DialogContent>
// stuff here without DialogTrigger
</DialogContent>
</Dialog>
}
Crazy antOP
@necm1 , I used tenstack data table. I am redirecting to editor from columns array . If I would use normal react component , I would not also bound the <Editor /> to every result of your table
so you would simply have one instance of the
Editor
componentCrazy antOP
@necm1 , Thanks for your reply, I will try your code to implement and let you know
@Crazy ant <@315806345376825344> , Thanks for your reply, I will try your code to implement and let you know
just let me know if you need help
Crazy antOP
@necm1 , Here onOpenChange is a function not a boolean value . Then in handleChange function how do you change its state
const handleOpenChange = (value: boolean) => {
setOpen(false);
onOpenChange(false);
}
Ok you are passing it as a props
just passing the state of the Dialog back to the ParentComponent
so you can update the state in the ParentComponent
Crazy antOP
Got it. Thanks @necm1 . It helped me.
@Crazy ant Got it. Thanks <@315806345376825344> . It helped me.
maybe with this approach, you wouldn't need to use
useQuery
at allbut you would have to pass the id like this then
Crazy antOP
Yes , with this approach I do not have to put any condition to useQuery. But howver I need to fetch items detail for this id.
ParentComponent.tsx:
const [openDialog, setOpenDialog] = useState(false);
const [currentId, setCurrentId] = useState<string | null>(null);
/*....*/
// your cell
cell: row => (
<div className="flex gap-4">
<Button
variant="outline"
className="item-container"
onClick={() => {
setCurrentId(row.getValue());
setOpenDialog(true)
}}
>Browse</Button>
</div>
)
return (
<>
// TABLE ETC....
<Editor id={currentId} open={openDialog} onOpenChange={(value: boolean) => setOpenDialog(false)} />
</>
)
so just the parent will tkae care of the id including the state
@Crazy ant Yes , with this approach I do not have to put any condition to useQuery. But howver I need to fetch items detail for this id.
don't you already have the data of the id trough the fetching? or do you just fetched the id?
Crazy antOP
no I do not have individual data. What I have in paranet component its items array. When I am clicking on a item from the table it must show the particular item detail. In a normal table component I would to below approach->
items.map((item)=>(<Table>.....<Table>)
from here I would push the whole item to the editor. In this case I do not need to fetch the item again with its id. But tanstack react table is different-> parent component:-> <DataTable columns={itemColumns} items={items} />
in columns:-> columnHelper.accessor('_id', {
cell: row => (
<div className="flex gap-4">
<Editor id={row.getValue()} />
</div>
),
header: () => <span>Action</span>,
}),
So I am not sure How do I push each whole item from this column. That's why I needed to fetch item based on its id.Crazy antOP
@necm1 , Could you please advise me how
if you want to send the whole row data
Crazy antOP
yes
just simply do this:
cell: (cell) => {
const row = cell.row.original;
console.log(row); // all data from the current row
return (
<div className="flex gap-4">
<Button
variant="outline"
className="item-container"
onClick={() => {
setCurrentItem(row);
setOpenDialog(true)
}}
>Browse</Button>
</div>
);
}
Crazy antOP
oh! Thanks . Just I need to push row. ok
Thank you so much @necm1 and all .
but yea, don't forget to refactor your
<Editor>
props and the stateAnswer
Crazy antOP
Ya that i will do in <Editor/>
Thank you @necm1
@Crazy ant Thank you <@315806345376825344>
if you face issues, feel free to reopen this thread and mention me
Crazy antOP
@necm1 , Thanks for your help. Now I modified the attached code . You can open it in any code editor. Its working but I am not satisfied with the code because in Editor I had to use useEffect since I required to show the currentItem when dialog is open. As per my opinion the code is not perfect since all other items also pushed into the editor, it only shows the current item when dialogue is opened. I am not sure whether this approach is good for bulk 1000 items during traffic, or we need to fetch individual item from database by its id when the dialogue is open.Please let me know your opinion.