Architectural question regarding nested Lists and Selects
Hey everyone! Here's a common problem where I hope there is a common solution in refine.
Imagine you have a custom row template component that looks close to something like this:
I want to use this component as a template for a
Form.List
(https://ant.design/components/form#components-form-demo-dynamic-form-item) component which enables you to dynamically add entries to a list. Say we have a list of 10 items then this component blocks the main-thread for ~5 seconds rendering all components because of the useSelect
.
I haven't found a way around this behavior yet, which as said completely blocks the main thread in my application. Maybe @core can help me figure this out 👼Form - Ant Design
An enterprise-class UI design language and React UI library with a set of high-quality React components, one of best React UI library for enterprises
14 Replies
Hi @bastianwegge. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
The
useSelect
hook in Refine is designed to fetch data from a resource and provide it as options for a select input. In your case, it seems like you're using useSelect
inside a component that is being rendered multiple times, which could be causing performance issues due to multiple network requests.
One possible solution could be to fetch the data for the select input at a higher level in your component hierarchy and pass it down to your MyCustomRowTemplate
component as a prop. This way, you only make one network request regardless of how many MyCustomRowTemplate
components you render.
Here's an example of how you could do this:
This way, you're only making one network request to fetch the categories, regardless of how many MyCustomRowTemplate
components you render.
For more information on how to use the useSelect
hook, you can refer to the Refine documentation (https://refine.dev/docs/ui-integrations/ant-design/hooks/use-select).
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@317433576721219584> kapa.ai is still learning and improving, please let us know how it did by reacting below
plain-purple•9mo ago
@kapa.ai So lets say I have 20 instances of this assignment and each one uses a different category, for simplicity lets say the used categories are 1, 10, 100 and 1000. How would I have to extend this example for the categories to be loaded? It's true that this might be a way to solve the freezing issue, but the categories are not being populated.
Let me check the knowledge base for you. One moment! :books:
----------------------
If each instance of your component needs to fetch a different category, you could modify the
useSelect
hook to fetch a specific category based on a prop. You would then pass the category ID as a prop to each instance of your component.
Here's an example of how you could do this:
In the parent component, you would then pass the category ID as a prop to each instance of MyCustomRowTemplate
:
This way, each instance of MyCustomRowTemplate
will fetch and display the category specified by its categoryId
prop.
For more information on how to use the useSelect
hook, you can refer to the Refine documentation (https://refine.dev/docs/ui-integrations/ant-design/hooks/use-select).
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@317433576721219584> kapa.ai is still learning and improving, please let us know how it did by reacting below
plain-purple•9mo ago
@kapa.ai that's basically what I did in the first place what caused the freezing or blocking-main-thread issue.
Let me check the knowledge base for you. One moment! :books:
----------------------
I see, I misunderstood your initial question. If each instance of your component needs to fetch a different category and you have a large number of these components, this could indeed lead to performance issues due to the large number of network requests.
One possible solution could be to fetch all categories at a higher level in your component hierarchy and then filter the categories for each instance of your component based on the category ID. This way, you only make one network request regardless of how many components you render.
Here's an example of how you could do this:
In this example, the
ParentComponent
fetches all categories and passes them as a prop to each instance of MyCustomRowTemplate
. Each instance of MyCustomRowTemplate
then finds the category with the matching ID from the categories
prop.
This approach should help to reduce the number of network requests and improve performance. However, it assumes that the number of categories is not too large. If you have a very large number of categories, this approach could still lead to performance issues due to the large amount of data being fetched and processed.
For more information on how to use the useQuery
hook, you can refer to the Refine documentation (https://refine.dev/docs/api-references/hooks/use-query).
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@317433576721219584> kapa.ai is still learning and improving, please let us know how it did by reacting below
plain-purple•9mo ago
@batuhanw @Omer do you have a solution for this? Mounting several components in a row that all need to have unique state regarding useSelect results in a complete freeze of the application. Moving the state into the parent components breaks the behavior of uniquely searchable selects for each row. Is there a common way you solve this problem?
plain-purple•9mo ago
@core I have created a repository with a detailed description here: https://github.com/bastianwegge/refine-dynamic-form-state
GitHub
GitHub - bastianwegge/refine-dynamic-form-state: This is a reproduc...
This is a reproduction of a problem we had in january 2024 in a project where we used refine - GitHub - bastianwegge/refine-dynamic-form-state: This is a reproduction of a problem we had in january...
exotic-emerald•8mo ago
Hey bastian, in the repository, I couldn't see multiple selects but I think you can conditionally enable select query as a solution.
exotic-emerald•8mo ago
When you provide
defaultValue
, useSelect makes request to get category with given ID, you can pass default value directly to Select component if you already have it.plain-purple•8mo ago
Thanks, that doesn't work unfortunately.
plain-purple•8mo ago
To make it clear, this is what I want to achieve: https://stackblitz.com/edit/react-g3vgzg?file=src%2FApp.js
But instead of the Phone No. I want to able to use a Select component like the one I used in my reproduction.
Dipesh Bajgain
StackBlitz
antd multi-level nested form - StackBlitz
A create-react-app project based on react and react-dom.