T
TanStack2w ago
passive-yellow

invalidateQueries does not work as expected

I have three different use cases of invalidateQueries, add user, ban/unban user and delete user, when I perform one of those actions it does not trigger a re-render, until I use removeQueries + refetchQueries for it to work
const createUserForm = useAppForm({
defaultValues: {
email: '',
password: '',
name: '',
role: 'user' as 'admin' | 'user',
},
validators: {
onChange: CreateUserSchema,
},
onSubmit: async ({ value }) => {
try {
await authClient.admin.createUser({
email: value.email,
password: value.password,
name: value.name,
role: value.role,
});
createUserForm.reset();
queryClient.removeQueries({
queryKey: ['users'],
});
queryClient.refetchQueries({
queryKey: ['users'],
});
// queryClient.invalidateQueries({
// queryKey: ['users'],
// });
} catch () {}
},
});
const createUserForm = useAppForm({
defaultValues: {
email: '',
password: '',
name: '',
role: 'user' as 'admin' | 'user',
},
validators: {
onChange: CreateUserSchema,
},
onSubmit: async ({ value }) => {
try {
await authClient.admin.createUser({
email: value.email,
password: value.password,
name: value.name,
role: value.role,
});
createUserForm.reset();
queryClient.removeQueries({
queryKey: ['users'],
});
queryClient.refetchQueries({
queryKey: ['users'],
});
// queryClient.invalidateQueries({
// queryKey: ['users'],
// });
} catch () {}
},
});
const fetchListUsers = async (): Promise<UserWithRole[]> => {
const data = await authClient.admin.listUsers(
{
query: {
limit: 50,
sortBy: 'createdAt',
sortDirection: 'desc',
},
},
{
throw: true,
}
);
return data?.users || [];
};

const useListUsersQuery = () =>
useQuery({
queryKey: ['users'],
queryFn: () => fetchListUsers(),
});
const fetchListUsers = async (): Promise<UserWithRole[]> => {
const data = await authClient.admin.listUsers(
{
query: {
limit: 50,
sortBy: 'createdAt',
sortDirection: 'desc',
},
},
{
throw: true,
}
);
return data?.users || [];
};

const useListUsersQuery = () =>
useQuery({
queryKey: ['users'],
queryFn: () => fetchListUsers(),
});
3 Replies
national-gold
national-gold2w ago
it will only trigger a re-render if the data returned by the refetch is different than what's already on screen. If you call invalidateQueries() and see a network request going out, it's working fine.
passive-yellow
passive-yellowOP2w ago
the issue is with my react-table implementation, I had to use useEffect to set the data after the refetch happens, as you pointed: it did a network request, but now handleDragEnd does not work
export function DataTable<UserWithRole>({
columns,
data: initialData,
onExportData,
}: DataTableProps<UserWithRole>) {
const [data, setData] = useState(() => initialData);
useEffect(() => {
setData(initialData);
}, [initialData]);

function handleDragEnd(event: DragEndEvent) {
const { active, over } = event;
if (active && over && active.id !== over.id) {
setData((data) => {
const oldIndex = dataIds.indexOf(active.id);
const newIndex = dataIds.indexOf(over.id);
return arrayMove(data, oldIndex, newIndex);
});
}
}
// in admin
<DataTable
columns={columns}
data={users}
onExportData={handleExportData}
/>
export function DataTable<UserWithRole>({
columns,
data: initialData,
onExportData,
}: DataTableProps<UserWithRole>) {
const [data, setData] = useState(() => initialData);
useEffect(() => {
setData(initialData);
}, [initialData]);

function handleDragEnd(event: DragEndEvent) {
const { active, over } = event;
if (active && over && active.id !== over.id) {
setData((data) => {
const oldIndex = dataIds.indexOf(active.id);
const newIndex = dataIds.indexOf(over.id);
return arrayMove(data, oldIndex, newIndex);
});
}
}
// in admin
<DataTable
columns={columns}
data={users}
onExportData={handleExportData}
/>
national-gold
national-gold2w ago
not sure what you're trying to achieve here but useEffects like this are usually an anti-pattern that you'd want to avoid.

Did you find this page helpful?