Skip to content
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

Fixed: Unnecessary API Calls and Re-Renders on Patient Page #9311

30 changes: 28 additions & 2 deletions src/components/Patient/ManagePatients.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import dayjs from "dayjs";
import { Link, navigate } from "raviger";
import { ReactNode, useCallback, useEffect, useState } from "react";
import { ReactNode, useCallback, useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";

import { Avatar } from "@/components/Common/Avatar";
Expand Down Expand Up @@ -289,8 +289,34 @@ export const PatientManager = () => {
return cleanedData;
};

// solving the issue Unnecessary API Calls and Re-Renders on Patient Page #9308
const [paramValue, setParamValue] = useState(params);
const previousValueRef = useRef(params);

function compareObjects(obj1: object, obj2: object) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you console 'params' you observe that two params coming in differently but looking the same were being treated as different values. This was causing unnecessary API calls. Upon examining the previous parameter value and the current incoming parameter value, I found they were different. This issue was occurring not only when typing inside the phone number field but also when changing the option, causing unnecessary API calls.

{page: 1, limit: 12, name: undefined, patient_no: undefined, is_active: 'True', …}
{page: '1', limit: 12, name: undefined, patient_no: undefined, is_active: 'True', …}

If you observe the page key value, the previous one is a number, and the current one is a string. This was the problem. I solved it by comparing two objects while ignoring their value types, which now prevents unnecessary API calls

const entries1 = Object.entries(obj1).map(([key, value]) => [
key,
String(value),
]);
const entries2 = Object.entries(obj2).map(([key, value]) => [
key,
String(value),
]);
entries1.sort(([key1], [key2]) => key1.localeCompare(key2));
entries2.sort(([key1], [key2]) => key1.localeCompare(key2));
return JSON.stringify(entries1) === JSON.stringify(entries2);
}

useEffect(() => {
if (compareObjects(previousValueRef.current, params)) {
return;
}
setParamValue(params);
previousValueRef.current = params;
}, [params]);

const { loading: isLoading, data } = useQuery(routes.patientList, {
query: params,
query: paramValue,
});

const getTheCategoryFromId = () => {
Expand Down
Loading