admin 管理员组

文章数量: 1086019

This error has been appearing on several pages throughout my site, and I can't figure out what exactly is going on here. I've followed the link in the error message that just leads to a github issue from several years ago, and found several other posts asking about this same issue, but it seems it's slightly different circumstances each time.

Here's the actual error text:

chunk-22DY4X5X.js?v=6b31ce6b:521 Warning: Cannot update a component (`OrderCreateForm`) while rendering a different component (`Controller`). To locate the bad setState() call inside `Controller`, follow the stack trace as described in 
    at Controller (http://localhost:5173/node_modules/.vite/deps/react-hook-form.js?v=6b31ce6b:321:35)
    at FormField (http://localhost:5173/src/components/ui/form.tsx:18:25)
    at div
    at form
    at FormProvider (http://localhost:5173/node_modules/.vite/deps/react-hook-form.js?v=6b31ce6b:103:11)
    at OrderCreateForm (http://localhost:5173/src/pages/order/create/form.tsx:34:43)...

I've narrowed down the error to happening here in the useEffect whenever the doctor_id value is set. The error only fires once on the initial practice selection; changing the practice again doesn't cause the error to fire.

// Watch the form value
const selectedPracticeId = form.watch("practice_id");

// Get doctors based on practice
const doctors = useGetDoctors(selectedPracticeId);

//Set defaults
useEffect(() => {
    if (doctors.data && doctors.data?.length === 1) {
        form.setValue("doctor_id", doctors.data[0].user_id);
      }
  }, [doctors.data]);

And the form itself, if needed:

<Form {...form}>
        <form
          onSubmit={form.handleSubmit(handleCreateOrder)}
          className="flex flex-col w-full gap-4"
        >
          {/* Top Row */}
          <div className="flex flex-wrap md:flex-nowrap gap-4">
            {/* Practice */}
            {practices.data && practices.data.length > 1 && (
              <FormField
                control={form.control}
                name="practice_id"
                rules={{
                  required: "Practice is required",
                  validate: (value) =>
                    practiceOptions?.some((option) => option.value === value) ||
                    "Selected practice is not valid",
                }}
                render={({ field }) => (
                  <FormItem className="w-full">
                    <FormLabel className="flex">Practice</FormLabel>
                    <FormControl>
                      <FormCombobox {...field} items={practiceOptions} />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />
            )}
            {/* Doctor */}
            <FormField
              control={form.control}
              name="doctor_id"
              rules={{
                required: "Doctor is required",
                validate: (value) =>
                  doctorOptions?.some((option) => option.value === value) ||
                  "Selected doctor is not valid",
              }}
              disabled={!form.watch("practice_id")}
              render={({ field }) => (
                <FormItem className="w-full">
                  <FormLabel className="flex">Doctor</FormLabel>
                  <FormControl>
                    <FormCombobox {...field} items={doctorOptions} />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />

Nothing I've tried resolves the issue. Settimeout is a common recommendation, though it's not a timing issue, so that does nothing. Using form.reset and setting the doctor_id there has the same issue as just using setValue. I can't think of anything else to try get this resolved.

This error has been appearing on several pages throughout my site, and I can't figure out what exactly is going on here. I've followed the link in the error message that just leads to a github issue from several years ago, and found several other posts asking about this same issue, but it seems it's slightly different circumstances each time.

Here's the actual error text:

chunk-22DY4X5X.js?v=6b31ce6b:521 Warning: Cannot update a component (`OrderCreateForm`) while rendering a different component (`Controller`). To locate the bad setState() call inside `Controller`, follow the stack trace as described in https://reactjs./link/setstate-in-render
    at Controller (http://localhost:5173/node_modules/.vite/deps/react-hook-form.js?v=6b31ce6b:321:35)
    at FormField (http://localhost:5173/src/components/ui/form.tsx:18:25)
    at div
    at form
    at FormProvider (http://localhost:5173/node_modules/.vite/deps/react-hook-form.js?v=6b31ce6b:103:11)
    at OrderCreateForm (http://localhost:5173/src/pages/order/create/form.tsx:34:43)...

I've narrowed down the error to happening here in the useEffect whenever the doctor_id value is set. The error only fires once on the initial practice selection; changing the practice again doesn't cause the error to fire.

// Watch the form value
const selectedPracticeId = form.watch("practice_id");

// Get doctors based on practice
const doctors = useGetDoctors(selectedPracticeId);

//Set defaults
useEffect(() => {
    if (doctors.data && doctors.data?.length === 1) {
        form.setValue("doctor_id", doctors.data[0].user_id);
      }
  }, [doctors.data]);

And the form itself, if needed:

<Form {...form}>
        <form
          onSubmit={form.handleSubmit(handleCreateOrder)}
          className="flex flex-col w-full gap-4"
        >
          {/* Top Row */}
          <div className="flex flex-wrap md:flex-nowrap gap-4">
            {/* Practice */}
            {practices.data && practices.data.length > 1 && (
              <FormField
                control={form.control}
                name="practice_id"
                rules={{
                  required: "Practice is required",
                  validate: (value) =>
                    practiceOptions?.some((option) => option.value === value) ||
                    "Selected practice is not valid",
                }}
                render={({ field }) => (
                  <FormItem className="w-full">
                    <FormLabel className="flex">Practice</FormLabel>
                    <FormControl>
                      <FormCombobox {...field} items={practiceOptions} />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />
            )}
            {/* Doctor */}
            <FormField
              control={form.control}
              name="doctor_id"
              rules={{
                required: "Doctor is required",
                validate: (value) =>
                  doctorOptions?.some((option) => option.value === value) ||
                  "Selected doctor is not valid",
              }}
              disabled={!form.watch("practice_id")}
              render={({ field }) => (
                <FormItem className="w-full">
                  <FormLabel className="flex">Doctor</FormLabel>
                  <FormControl>
                    <FormCombobox {...field} items={doctorOptions} />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />

Nothing I've tried resolves the issue. Settimeout is a common recommendation, though it's not a timing issue, so that does nothing. Using form.reset and setting the doctor_id there has the same issue as just using setValue. I can't think of anything else to try get this resolved.

Share Improve this question edited Mar 27 at 21:37 hego64 asked Mar 27 at 18:20 hego64hego64 3651 gold badge7 silver badges21 bronze badges 2
  • Please try to edit to include a complete minimal reproducible example that reproduces the warning/error. Include also a complete error message and any stacktraces, and any debugging logs and details. – Drew Reese Commented Mar 27 at 21:31
  • What is form? How is it related to OrderCreateForm? It seems it is obtained from FormProvider. Share more debugging details. – Chukwujiobi Canon Commented Mar 27 at 22:11
Add a comment  | 

1 Answer 1

Reset to default 0

You cannot use form.setValue() to update the FormProvider component obtained from react-hook-form during the render of OrderCreateForm.

Instead, invoke form.setValue() after render not during render.

本文标签: javascriptCannot update a component while rendering a different component (controller)Stack Overflow