Skip to content

Commit ed7cc92

Browse files
authored
Merge pull request #170 from CommerceBear/bugfix/fix-json-issubmitting
Fix isSubmitting state value when using encType application/json
2 parents 7523369 + 1c0b498 commit ed7cc92

File tree

3 files changed

+81
-12
lines changed

3 files changed

+81
-12
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/hook/index.test.tsx

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ const fetcherSubmitMock = vi.fn();
1616
const useActionDataMock = vi.hoisted(() => vi.fn());
1717

1818
const useNavigationMock = vi.hoisted(() =>
19-
vi.fn<() => Pick<Navigation, "state" | "formData">>(() => ({
19+
vi.fn<() => Pick<Navigation, "state" | "formData" | "json">>(() => ({
2020
state: "idle",
2121
formData: undefined,
22+
json: undefined,
2223
})),
2324
);
2425

@@ -290,12 +291,70 @@ describe("useRemixForm", () => {
290291
useNavigationMock.mockReturnValue({
291292
state: "submitting",
292293
formData: new FormData(),
294+
json: undefined,
293295
});
294296
rerender();
295297

296298
expect(result.current.formState.isSubmitting).toBe(true);
297299

298-
useNavigationMock.mockReturnValue({ state: "idle", formData: undefined });
300+
useNavigationMock.mockReturnValue({
301+
state: "idle",
302+
formData: undefined,
303+
json: undefined,
304+
});
305+
rerender();
306+
307+
expect(result.current.formState.isSubmitting).toBe(false);
308+
});
309+
310+
it("should reset isSubmitting when the form is submitted using encType: application/json", async () => {
311+
submitMock.mockReset();
312+
useNavigationMock.mockClear();
313+
314+
const { result, rerender } = renderHook(() =>
315+
useRemixForm({
316+
resolver: () => ({ values: {}, errors: {} }),
317+
submitConfig: {
318+
action: "/submit",
319+
encType: "application/json",
320+
},
321+
}),
322+
);
323+
324+
expect(result.current.formState.isSubmitting).toBe(false);
325+
326+
act(() => {
327+
result.current.handleSubmit({} as any);
328+
});
329+
expect(result.current.formState.isSubmitting).toBe(true);
330+
331+
await waitFor(() => expect(submitMock).toHaveBeenCalledTimes(1));
332+
333+
expect(result.current.formState.isSubmitting).toBe(true);
334+
335+
expect(submitMock).toHaveBeenCalledWith(
336+
{},
337+
{
338+
method: "post",
339+
action: "/submit",
340+
encType: "application/json",
341+
},
342+
);
343+
344+
useNavigationMock.mockReturnValue({
345+
state: "submitting",
346+
formData: undefined,
347+
json: {},
348+
});
349+
rerender();
350+
351+
expect(result.current.formState.isSubmitting).toBe(true);
352+
353+
useNavigationMock.mockReturnValue({
354+
state: "idle",
355+
formData: undefined,
356+
json: undefined,
357+
});
299358
rerender();
300359

301360
expect(result.current.formState.isSubmitting).toBe(false);

src/hook/index.tsx

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,24 @@ export const useRemixForm = <
7878
const methods = useForm({ ...formProps, errors: data?.errors });
7979
const navigation = useNavigation();
8080
// Either it's submitted to an action or submitted to a fetcher (or neither)
81-
const isSubmittingForm = useMemo(
82-
() =>
83-
Boolean(
84-
(navigation.state !== "idle" && navigation.formData !== undefined) ||
85-
(fetcher?.state !== "idle" && fetcher?.formData !== undefined),
86-
),
87-
[navigation.state, navigation.formData, fetcher?.state, fetcher?.formData],
88-
);
81+
const isSubmittingForm = useMemo(() => {
82+
const navigationIsSubmitting =
83+
navigation.state !== "idle" &&
84+
(navigation.formData ?? navigation.json) !== undefined;
85+
86+
const fetcherIsSubmitting =
87+
fetcher?.state !== "idle" &&
88+
(fetcher?.formData ?? fetcher?.json) !== undefined;
89+
90+
return navigationIsSubmitting || fetcherIsSubmitting;
91+
}, [
92+
navigation.state,
93+
navigation.formData,
94+
navigation.json,
95+
fetcher?.state,
96+
fetcher?.formData,
97+
fetcher?.json,
98+
]);
8999

90100
// A state to keep track whether we're actually submitting the form through the network
91101
const [isSubmittingNetwork, setIsSubmittingNetwork] = useState(false);

0 commit comments

Comments
 (0)