Skip to content

Commit 379470c

Browse files
authored
Merge pull request #169 from CommerceBear/bugfix/remix_branch/fix-json-issubmitting
Fix isSubmitting formState when encType is application/json for Remix.run
2 parents c92c241 + 8003965 commit 379470c

3 files changed

Lines changed: 82 additions & 13 deletions

File tree

package-lock.json

Lines changed: 3 additions & 3 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

@@ -249,12 +250,70 @@ describe("useRemixForm", () => {
249250
useNavigationMock.mockReturnValue({
250251
state: "submitting",
251252
formData: new FormData(),
253+
json: undefined,
252254
});
253255
rerender();
254256

255257
expect(result.current.formState.isSubmitting).toBe(true);
256258

257-
useNavigationMock.mockReturnValue({ state: "idle", formData: undefined });
259+
useNavigationMock.mockReturnValue({
260+
state: "idle",
261+
formData: undefined,
262+
json: undefined,
263+
});
264+
rerender();
265+
266+
expect(result.current.formState.isSubmitting).toBe(false);
267+
});
268+
269+
it("should reset isSubmitting when the form is submitted using encType: application/json", async () => {
270+
submitMock.mockReset();
271+
useNavigationMock.mockClear();
272+
273+
const { result, rerender } = renderHook(() =>
274+
useRemixForm({
275+
resolver: () => ({ values: {}, errors: {} }),
276+
submitConfig: {
277+
action: "/submit",
278+
encType: "application/json",
279+
},
280+
}),
281+
);
282+
283+
expect(result.current.formState.isSubmitting).toBe(false);
284+
285+
act(() => {
286+
result.current.handleSubmit({} as any);
287+
});
288+
expect(result.current.formState.isSubmitting).toBe(true);
289+
290+
await waitFor(() => expect(submitMock).toHaveBeenCalledTimes(1));
291+
292+
expect(result.current.formState.isSubmitting).toBe(true);
293+
294+
expect(submitMock).toHaveBeenCalledWith(
295+
{},
296+
{
297+
method: "post",
298+
action: "/submit",
299+
encType: "application/json",
300+
},
301+
);
302+
303+
useNavigationMock.mockReturnValue({
304+
state: "submitting",
305+
formData: undefined,
306+
json: {},
307+
});
308+
rerender();
309+
310+
expect(result.current.formState.isSubmitting).toBe(true);
311+
312+
useNavigationMock.mockReturnValue({
313+
state: "idle",
314+
formData: undefined,
315+
json: undefined,
316+
});
258317
rerender();
259318

260319
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
@@ -67,14 +67,24 @@ export const useRemixForm = <T extends FieldValues>({
6767
const methods = useForm<T>({ ...formProps, errors: data?.errors });
6868
const navigation = useNavigation();
6969
// Either it's submitted to an action or submitted to a fetcher (or neither)
70-
const isSubmittingForm = useMemo(
71-
() =>
72-
Boolean(
73-
(navigation.state !== "idle" && navigation.formData !== undefined) ||
74-
(fetcher?.state !== "idle" && fetcher?.formData !== undefined),
75-
),
76-
[navigation.state, navigation.formData, fetcher?.state, fetcher?.formData],
77-
);
70+
const isSubmittingForm = useMemo(() => {
71+
const navigationIsSubmitting =
72+
navigation.state !== "idle" &&
73+
(navigation.formData ?? navigation.json) !== undefined;
74+
75+
const fetcherIsSubmitting =
76+
fetcher?.state !== "idle" &&
77+
(fetcher?.formData ?? fetcher?.json) !== undefined;
78+
79+
return navigationIsSubmitting || fetcherIsSubmitting;
80+
}, [
81+
navigation.state,
82+
navigation.formData,
83+
navigation.json,
84+
fetcher?.state,
85+
fetcher?.formData,
86+
fetcher?.json,
87+
]);
7888

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

0 commit comments

Comments
 (0)