Skip to content

Commit

Permalink
Fix loop caused by unstable reference
Browse files Browse the repository at this point in the history
  • Loading branch information
gustavlrsn committed Dec 19, 2024
1 parent f208618 commit 1a20836
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 40 deletions.
33 changes: 15 additions & 18 deletions components/expenses/EditExpenseDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ const RenderFormFields = ({ field, onSubmit, expense }) => {
}
};
const EditPayee = ({ expense, onSubmit }) => {
const { LoggedInUser } = useLoggedInUser();
const formRef = React.useRef<HTMLFormElement>();
const startOptions = React.useRef({
expenseId: expense.legacyId,
isInlineEdit: true,
pickSchemaFields: { expenseItems: true, hasTax: true, tax: true, payoutMethodId: true, payeeSlug: true },
});
const transformedOnSubmit = React.useCallback(
async (values, h, formOptions) => {
Expand Down Expand Up @@ -91,7 +91,7 @@ const EditPayee = ({ expense, onSubmit }) => {
};
return onSubmit(editValues);
},
[LoggedInUser],
[expense.payee.slug, onSubmit],
);

const expenseForm = useExpenseForm({
Expand All @@ -118,7 +118,6 @@ const EditPayee = ({ expense, onSubmit }) => {
},
startOptions: startOptions.current,
onSubmit: transformedOnSubmit,
pickSchemaFields: { expenseItems: true, hasTax: true, tax: true, payoutMethodId: true, payeeSlug: true },
});

const hasChangedPayee =
Expand Down Expand Up @@ -151,6 +150,14 @@ const EditPayoutMethod = ({ expense, onSubmit }) => {
const startOptions = React.useRef({
expenseId: expense.legacyId,
isInlineEdit: true,
pickSchemaFiels: {
expenseItems: true,
hasTax: true,
tax: true,
payoutMethodId: true,
payee: true,
payeeLocation: true,
},
});
const transformedOnSubmit = React.useCallback(
async (values, h, formOptions) => {
Expand Down Expand Up @@ -184,7 +191,7 @@ const EditPayoutMethod = ({ expense, onSubmit }) => {
};
return onSubmit(editValues);
},
[LoggedInUser],
[onSubmit],
);

const expenseForm = useExpenseForm({
Expand All @@ -210,14 +217,6 @@ const EditPayoutMethod = ({ expense, onSubmit }) => {
},
startOptions: startOptions.current,
onSubmit: transformedOnSubmit,
pickSchemaFields: {
expenseItems: true,
hasTax: true,
tax: true,
payoutMethodId: true,
payee: true,
payeeLocation: true,
},
});

return (
Expand All @@ -234,6 +233,7 @@ const EditAttachments = ({ expense, onSubmit }) => {
const startOptions = React.useRef({
expenseId: expense.legacyId,
isInlineEdit: true,
pickSchemaFields: { expenseAttachedFiles: true },
});
const transformedOnSubmit = values => {
const editValues = {
Expand Down Expand Up @@ -269,7 +269,6 @@ const EditAttachments = ({ expense, onSubmit }) => {
},
startOptions: startOptions.current,
onSubmit: transformedOnSubmit,
pickSchemaFields: { expenseAttachedFiles: true },
});

return (
Expand All @@ -285,7 +284,8 @@ const EditExpenseItems = ({ expense, onSubmit }) => {
const formRef = React.useRef<HTMLFormElement>();
const startOptions = React.useRef({
expenseId: expense.legacyId,
isInlineEdit: true,
isInlineEdit: false,
pickSchemaFields: { expenseItems: true, hasTax: true, tax: true },
});
const transformedOnSubmit = values => {
const editValues = {
Expand Down Expand Up @@ -333,7 +333,6 @@ const EditExpenseItems = ({ expense, onSubmit }) => {
},
startOptions: startOptions.current,
onSubmit: transformedOnSubmit,
pickSchemaFields: { expenseItems: true, hasTax: true, tax: true },
});

return (
Expand Down Expand Up @@ -405,8 +404,6 @@ export default function EditExpenseDialog({
goToLegacyEdit?: () => void;
}) {
const [open, setOpen] = React.useState(false);

const { LoggedInUser } = useLoggedInUser();
const intl = useIntl();
const [editExpense] = useMutation(
gql`
Expand Down Expand Up @@ -446,7 +443,7 @@ export default function EditExpenseDialog({
toast({ variant: 'error', message: i18nGraphqlException(intl, err) });
}
},
[LoggedInUser, editExpense, intl, toast],
[editExpense, intl, expense.id],
);
return (
<Dialog open={open} onOpenChange={setOpen}>
Expand Down
75 changes: 53 additions & 22 deletions components/submit-expense/useExpenseForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ import { loggedInAccountExpensePayoutFieldsFragment } from '../expenses/graphql/
import { validatePayoutMethod } from '../expenses/PayoutMethodForm';
import { getCustomZodErrorMap } from '../FormikZod';

function usePreviousValues<T extends Record<string, any>>(values: T) {
const ref = React.useRef<T>();

React.useEffect(() => {
ref.current = values;
});

return ref.current;
}

export enum InviteeAccountType {
INDIVIDUAL = 'INDIVIDUAL',
ORGANIZATION = 'ORGANIZATION',
Expand Down Expand Up @@ -1167,7 +1177,6 @@ async function buildFormOptions(
values: ExpenseFormValues,
startOptions: ExpenseFormStartOptions,
refresh?: boolean,
pickSchemaFields?: Record<string, boolean>,
): Promise<ExpenseFormOptions> {
const options: ExpenseFormOptions = { schema: z.object({}) };

Expand Down Expand Up @@ -1309,7 +1318,7 @@ async function buildFormOptions(
options.totalInvoicedInExpenseCurrency = totalInvoiced;
}

options.schema = buildFormSchema(values, options, intl, pickSchemaFields);
options.schema = buildFormSchema(values, options, intl, startOptions.pickSchemaFields);

return options;
} catch (err) {
Expand Down Expand Up @@ -1344,6 +1353,7 @@ type ExpenseFormStartOptions = {
expenseId?: number;
draftKey?: string;
isInlineEdit?: boolean;
pickSchemaFields?: Record<string, boolean>;
};

export function useExpenseForm(opts: {
Expand All @@ -1356,7 +1366,6 @@ export function useExpenseForm(opts: {
options: ExpenseFormOptions,
startOptions: ExpenseFormStartOptions,
) => void | Promise<any>;
pickSchemaFields?: Record<string, boolean>;
}): ExpenseForm {
const intl = useIntl();
const apolloClient = useApolloClient();
Expand Down Expand Up @@ -1617,19 +1626,49 @@ export function useExpenseForm(opts: {
setStatus({ schema: formOptions.schema });
}, [formOptions.schema, setStatus]);

const dependencyValues = {
apolloClient, // Example: use whatever variables you have in your dependency array
LoggedInUser,
expenseFormValues: expenseForm.values,
startOptions,
formOptionsSchema: formOptions.schema,
validateForm: expenseForm.validateForm,
formOptionsExpenseCurrency: formOptions.expenseCurrency,
expenseFormValuesExpenseItems: expenseForm.values.expenseItems,
setFieldValue: setFieldValue,
formOptionsPayoutMethods: formOptions.payoutMethods,
expenseFormValuesPayoutMethodId: expenseForm.values.payoutMethodId,
};

const prevDependencies = usePreviousValues(dependencyValues);

React.useEffect(() => {
Object.entries(dependencyValues).forEach(([key, currentValue]) => {
if (prevDependencies && prevDependencies[key] !== currentValue) {
console.log(`Dependency "${key}" changed from ${prevDependencies[key]} to ${currentValue}`);

Check failure on line 1648 in components/submit-expense/useExpenseForm.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected console statement
}
});

// Your original effect code
}, [
dependencyValues.apolloClient, // Example: use whatever variables you have in your dependency array
dependencyValues.LoggedInUser,
dependencyValues.expenseFormValues,
dependencyValues.startOptions,
dependencyValues.formOptionsSchema,
dependencyValues.validateForm,
dependencyValues.formOptionsExpenseCurrency,
dependencyValues.expenseFormValuesExpenseItems,
dependencyValues.setFieldValue,
dependencyValues.formOptionsPayoutMethods,
dependencyValues.expenseFormValuesPayoutMethodId,
]);

// calculate form
React.useEffect(() => {
async function refreshFormOptions() {
setFormOptions(
await buildFormOptions(
intl,
apolloClient,
LoggedInUser,
expenseForm.values,
startOptions.current,
false,
opts.pickSchemaFields,
),
await buildFormOptions(intl, apolloClient, LoggedInUser, expenseForm.values, startOptions.current),
);
if (!startOptions.current.expenseId) {
initialLoading.current = false;
Expand All @@ -1639,7 +1678,7 @@ export function useExpenseForm(opts: {
}

refreshFormOptions();
}, [apolloClient, LoggedInUser, expenseForm.values, intl, startOptions, opts.pickSchemaFields]);
}, [apolloClient, LoggedInUser, expenseForm.values, intl, startOptions]);

// revalidate form
const validateForm = expenseForm.validateForm;
Expand Down Expand Up @@ -1672,15 +1711,7 @@ export function useExpenseForm(opts: {
initialLoading: initialLoading.current,
refresh: async () =>
setFormOptions(
await buildFormOptions(
intl,
apolloClient,
LoggedInUser,
expenseForm.values,
startOptions.current,
true,
opts.pickSchemaFields,
),
await buildFormOptions(intl, apolloClient, LoggedInUser, expenseForm.values, startOptions.current, true),
),
});
}

0 comments on commit 1a20836

Please sign in to comment.