-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG] Conditional Triggering in useMany with Support for Query Arrays #6449
Comments
Hey @aress31 thanks for the issue. You can use supabase join strings to query relationships, you can check our documentation on this one here: https://refine.dev/docs/data/packages/supabase/#select---handling-one-to-many-relationship For example:
|
@BatuhanW, thanks for the reply. I understand your point about sending only one request to the database, but that's not always feasible due to application design or other constraints, so enhanced support for multiple requests would be really helpful. Additionally, in my case, the resources are defined at the top level, though I’m not sure if that impacts anything here. Another issue I'm noticing is that the parent metadata doesn’t seem to be respected, resulting in the entire table being fetched rather than just the entries linked to the parent. --- SNIP ---
const createResource = (name, parentResource) => {
const basePath = parentResource
? `/:tenantId/${parentResource}/:${singular(parentResource)}Id/${name}`
: `/:tenantId/${name}`;
return {
name,
list: basePath,
show: `${basePath}/show/:id`,
edit: `${basePath}/edit/:id`,
create: `${basePath}/create`,
...(parentResource && { meta: { parent: parentResource } }),
};
};
const resources = [
createResource("projects"),
createResource("applications", "projects"),
--- SNIP ---
];
const SidebarLayout = () => {
--- SNIP ---
return (
<Refine
dataProvider={dataProvider(supabaseClient)}
liveProvider={liveProvider(supabaseClient)}
routerProvider={routerProvider}
options={{
liveMode: "auto",
syncWithLocation: true,
warnWhenUnsavedChanges: true,
}}
--- SNIP ---
resources={resources}
>
--- SNIP ---
</Refine>
);
};
export default SidebarLayout; |
Hello @ aress31, I tried reproducing your issue, and everything works as expected. import { useMany } from "@refinedev/core";
import { useState } from "react";
export const UseManyExample = () => {
const [query, setQuery] = useState<{
resource: string;
ids: number[];
}>({
resource: "",
ids: [],
});
const { data, isLoading } = useMany({
...query,
queryOptions: { enabled: query.resource !== "" },
});
return (
<div>
<button onClick={() => setQuery({ resource: "posts", ids: [1, 2, 3] })}>
Load Posts
</button>
<button
onClick={() => setQuery({ resource: "categories", ids: [1, 2, 3] })}
>
Load Categories
</button>
<div>useMany isLoading: {isLoading.toString()}</div>
<br />
<div>
{data?.data.map((item) => (
<div
key={item.id}
style={{
display: "flex",
gap: "4px",
}}
>
<div>{item.id}</div>
<div>{item.title}</div>
</div>
))}
</div>
</div>
);
}; Screen.Recording.2024-11-05.at.10.06.17.movFor supporting multiple resources, I don’t think For example: import { useMany } from "@refinedev/core";
export const UseManyMultipleResourceExample = () => {
return (
<div>
<GetManyResources resource="posts" ids={[1, 2, 3]} title="Posts" />
<br />
<GetManyResources
resource="categories"
ids={[1, 2, 3]}
title="Categories"
/>
</div>
);
};
export const GetManyResources = (props: {
title?: string;
resource: string;
ids: number[];
}) => {
const { data, isLoading } = useMany({
resource: props.resource,
ids: props.ids,
});
return (
<div>
<h1>{props.title}</h1>
{data?.data.map((item) => (
<div
key={item.id}
style={{
display: "flex",
gap: "4px",
}}
>
<div>{item.id}</div>
<div>{item.title}</div>
</div>
))}
</div>
);
}; Do you see any downsides to this method that I might be missing? |
@alicanerdurmaz I understand now; the idea is to let specific components handle the loading process. Initially, I was loading multiple sets of data in the parent component using multiple useMany calls and passing the data down. My approach was to fetch data from tables and, if those tables had foreign key references, use useMany to load the related data. However, I ended up using the !inner solution, which is cleaner and more efficient (thanks for the tip, @BatuhanW - only downside is longer initial loading/rendering time as more data are transmitted). In cases where there are multiple foreign keys and therefore several linked data sets, is it possible to chain inner statements? I haven't seen documentation on this, as far as I know. EDIT: @alicanerdurmaz, one drawback of useMany not supporting multiple queries is when you need data that isn’t linked by any relationship but is required within the same component. Thoughts? |
@aress31 I believe it’s possible, but I didn’t fully understand the scenario. If you provide more details about it, I might be able to come up with some example code. |
@aress31 I believe there is no bug here. You don't want to join in other tables in the initial query, so you would need to fetch separately. Closing the issue now. Feel free to re-open it if needed. |
Describe the bug
There are a few use cases that
useMany
does not currently seem to support, specifically:In this scenario, I want to trigger
useMany
only when there is a column with a foreign key. I have attempted to adjust the hooks, but this particular use case does not seem to be supported yet.Steps To Reproduce
DataGridView
component whereuseMany
is used.dataGridProps
.useMany
reacts when there are no foreign key columns.Expected behavior
The
useMany
hook should only run when certain conditions are met, like having foreign key columns or valid resource identifiers. This helps avoid unnecessary API calls when there's nothing relevant to fetch, making the app faster and smoother. Plus, it would be awesome to support an array of queries to grab multiple related resources at once, which would make data fetching even more efficient.Packages
Additional Context
No response
The text was updated successfully, but these errors were encountered: