absent-sapphire
absent-sapphire14mo ago

Best way to call multiple useList

I want to call multiple useList for multiple data to map in multiple selects on my page. I already have 1: export const PatientCreatePage: React.FC<PropsWithChildren> = ({ children, }) => { const { data, isLoading, isError } = useList<TCountry, HttpError>({ resource: 'dataCountryList', });
if (isLoading) { return <div>Loading countries...</div>; }
if (isError) { return <div>Error loading countries!</div>; }
const countryList = data?.data; return ( <> <Modal><Form><Form.Item /> <Select options={ countryList?.map((country) => ( { label: country.name, value: country.country_id, }))}/> </Form.Item></Form></Modal>{children}</> ); }; It's working well, but if I want to add another let's say TState, TCity, TDistrict. Do I have to write that long code out again for each of them? Can I put them in another file and get the data here and assigned them to each selects. What's the best most conventional way, shorter code, same functionalities
2 Replies
kapa.ai
kapa.ai14mo ago
Hi @lukevo.. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Yes, you can certainly abstract the useList hook into a separate function and reuse it for different resources. This will help you avoid repeating the same code for each resource. Here's an example of how you can do it:
// useResourceList.js
import { useList, HttpError } from "@refinedev/core";

export const useResourceList = (resource) => {
const { data, isLoading, isError } = useList(resource);

if (isLoading) {
return { isLoading: true };
}

if (isError) {
return { isError: true };
}

const dataList = data?.data;

return { dataList };
};
// useResourceList.js
import { useList, HttpError } from "@refinedev/core";

export const useResourceList = (resource) => {
const { data, isLoading, isError } = useList(resource);

if (isLoading) {
return { isLoading: true };
}

if (isError) {
return { isError: true };
}

const dataList = data?.data;

return { dataList };
};
Then, in your component, you can use this function to fetch data for different resources:
// PatientCreatePage.js
import { useResourceList } from './useResourceList';

export const PatientCreatePage: React.FC<PropsWithChildren> = ({ children }) => {
const { dataList: countryList, isLoading: isCountryLoading, isError: isCountryError } = useResourceList('dataCountryList');
const { dataList: stateList, isLoading: isStateLoading, isError: isStateError } = useResourceList('dataStateList');
const { dataList: cityList, isLoading: isCityLoading, isError: isCityError } = useResourceList('dataCityList');
const { dataList: districtList, isLoading: isDistrictLoading, isError: isDistrictError } = useResourceList('dataDistrictList');

if (isCountryLoading || isStateLoading || isCityLoading || isDistrictLoading) {
return <div>Loading...</div>;
}

if (isCountryError || isStateError || isCityError || isDistrictError) {
return <div>Error loading data!</div>;
}
return (
<>
<Modal>
<Form>
<Form.Item>
<Select options={countryList?.map((country) => ({ label: country.name, value: country.country_id }))} />
<Select options={stateList?.map((state) => ({ label: state.name, value: state.state_id }))} />
<Select options={cityList?.map((city) => ({ label: city.name, value: city.city_id }))} />
<Select options={districtList?.map((district) => ({ label: district.name, value: district.district_id }))} />
</Form.Item>
</Form>
</Modal>
{children}
</>
);
};
// PatientCreatePage.js
import { useResourceList } from './useResourceList';

export const PatientCreatePage: React.FC<PropsWithChildren> = ({ children }) => {
const { dataList: countryList, isLoading: isCountryLoading, isError: isCountryError } = useResourceList('dataCountryList');
const { dataList: stateList, isLoading: isStateLoading, isError: isStateError } = useResourceList('dataStateList');
const { dataList: cityList, isLoading: isCityLoading, isError: isCityError } = useResourceList('dataCityList');
const { dataList: districtList, isLoading: isDistrictLoading, isError: isDistrictError } = useResourceList('dataDistrictList');

if (isCountryLoading || isStateLoading || isCityLoading || isDistrictLoading) {
return <div>Loading...</div>;
}

if (isCountryError || isStateError || isCityError || isDistrictError) {
return <div>Error loading data!</div>;
}
return (
<>
<Modal>
<Form>
<Form.Item>
<Select options={countryList?.map((country) => ({ label: country.name, value: country.country_id }))} />
<Select options={stateList?.map((state) => ({ label: state.name, value: state.state_id }))} />
<Select options={cityList?.map((city) => ({ label: city.name, value: city.city_id }))} />
<Select options={districtList?.map((district) => ({ label: district.name, value: district.district_id }))} />
</Form.Item>
</Form>
</Modal>
{children}
</>
);
};
This way, you can keep your code DRY (Don't Repeat Yourself) and maintainable. The useResourceList function can be reused for any resource, and it encapsulates the logic of fetching data and handling loading and error states. Please note that the structure of the data depends on your API. In this example, it's assumed that each resource item has a name and an id field. For more information, you can refer to the useList documentation (https://refine.dev/docs/api-reference/core/hooks/data/useList/). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai14mo ago
<@582491401715974144> kapa.ai is still learning and improving, please let us know how it did by reacting below