SWR 根据下拉列表中的选定值获取数据

SWR fetch data based on selected value in dropdown

在 swr 中是否可以根据下拉列表中的 selected 值获取数据?起初获取它是有效的,但是当我 select 以前的 selected 值时,它不会获取正确的数据。

  1. 获取API
   const { data: entities } = useSWR(
       currentEntity?.entity_id
         ? "/api/entities/" + currentEntity?.entity_id
         : null,
       { dedupingInterval: 12000 }
     );
  1. 这就是我在 return
  2. 时呈现数据的方式
     {!isEmptyObject(individual) &&
                  isTabThree &&
                  selectedEntity === "" ? (
                    <div className="flex items-center justify-center h-48 text-gray-500">
                      Please choose an entity
                    </div>
                  ) : !entities ? (
                    <div className="flex items-center justify-center h-48">
                      <ThreeDotsSpinner />
                    </div>
                  ) : (
                    <EntityForm data={entities} />
                  )}
  1. 这是将数据存储在输入中的实体表单,所需的行为是每当下拉列表更改时,表单也会通过获取更改为正确的数据 api
    export default function EntityForm({ data }) {
    
      
      const formik = useFormik({
        initialValues: {
          company_name: data?.company_name ?? "",
          company_type: data?.company_type ?? "",
          company_industry: data?.company_industry ?? "",
          company_address: {
            addresss_line1: data?.company_address?.addresss_line1 ?? "",
            addresss_line2: data?.company_address?.addresss_line2 ?? "",
            city: data?.company_address?.city ?? "",
            province: data?.company_address?.province ?? "",
          },
          company_operations: data?.company_operations ?? "",
          company_monthly_income: data?.company_monthly_income ?? "",
          company_sss: data?.company_sss ?? "",
          company_website: data?.company_website ?? "",
          company_tin: data?.company_tin ?? "",
          company_contact_number: data?.company_contact_number ?? "",
          representative_first_name: data?.representative_first_name ?? "",
          representative_last_name: data?.representative_last_name ?? "",
          representative_position: data?.representative_position ?? "",
          representative_contact_number: data?.representative_contact_number ?? "",
          representative_email: data?.representative_email ?? "",
          representative_employed_duration:
            data?.representative_employed_duration ?? "",
          documents: [],
        },
      });
      return (
        <FormikProvider value={formik}>
          <Form>
            <>
              <header className="absolute right-0 top-40">
                <nav className="mr-6">
                  <Link href="/admin/customers">
                    <a className="text-sm text-gray-500 mr-9">Back</a>
                  </Link>
                  <Button type="submit" className="btn-primary">
                    Update
                  </Button>
                </nav>
              </header>
              <div>
                <h3 className="my-4 text-xs text-gray-400">
                  Applicable if you want to apply loan using your business.
                </h3>
    
                <main className="space-y-10">
                  <section>
                    <h2 className="mb-9">Business Information</h2>
    
                    <div className="grid gap-y-7">
                      <div className="grid grid-cols-3 gap-x-7">
                        <Input
                          label="Business Name"
                          name="company_name"
                          placeholder="Tom Tech"
                        />
                        <div>
                          <ListBox
                            label="Type of Business"
                            options={typeOfBusiness}
                            value={formik.values.company_type}
                            name="company_type"
                            placeholder="Sole Proprieter"
                          />
                        </div>
                        <div>
                          <ListBox
                            label="Type of Business"
                            options={industryData}
                            value={formik.values.company_industry}
                            name="company_industry"
                            placeholder="Tech"
                          />
                        </div>
                      </div>
    
                      <div className="grid grid-cols-2 gap-7">
                        <Input
                          label="Address Line 1"
                          name="company_address.addresss_line1"
                          placeholder="123 Kanto St."
                        />
                        <Input
                          label="Address Line 2"
                          name="company_address.addresss_line2"
                          placeholder="123 Kanto St."
                        />
                        <div>
                          <ListBox
                            label="City/Municipality"
                            options={cityData}
                            value={formik.values.company_address.city}
                            name="company_address.city"
                            placeholder="Manila"
                          />
                        </div>
                        <div>
                          <ListBox
                            label="City/Municipality"
                            options={provinceData}
                            value={formik.values.company_address.province}
                            name="company_address.province"
                            placeholder="Metro Manila"
                          />
                        </div>
                      </div>
    
                      <div className="grid grid-cols-3 gap-7">
                        <Input
                          label="Years of Operation"
                          type="number"
                          name="company_operations"
                          placeholder="20 Years"
                        />
                        <Input
                          label="Average Monthly Income"
                          type="number"
                          name="company_monthly_income"
                          placeholder="Php 50,000"
                        />
                        <Input
                          label="Company Website"
                          name="company_website"
                          placeholder="https://tom.tech"
                        />
                        <Input
                          label="Company SSS"
                          name="company_sss"
                          placeholder="000-123-234-345"
                        />
                        <Input
                          label="Company TIN"
                          name="company_tin"
                          placeholder="06-98723452"
                        />
                        <Input
                          label="Company Tel. No."
                          name="company_contact_number"
                          placeholder="749-8463"
                        />
                      </div>
                    </div>
                  </section>
    
                  <section>
                    <h2 className="mb-9">Representative Details</h2>
    
                    <div className="grid grid-cols-3 gap-7">
                      <Input
                        label="First Name"
                        name="representative_first_name"
                        placeholder="Tom"
                      />
                      <Input
                        label="Last Name"
                        name="representative_last_name"
                        placeholder="Doe"
                      />
    
                      <Input
                        label="Position"
                        name="representative_position"
                        placeholder="Proprietor"
                      />
                      <Input
                        label="Contact Number"
                        name="representative_contact_number"
                        placeholder="Proprietor"
                      />
                      <Input
                        label="Email"
                        type="email"
                        name="representative_email"
                        placeholder="email@email.com"
                      />
    
                      <Input
                        label="Years Employed"
                        type="number"
                        name="representative_employed_duration"
                        placeholder="20 Years"
                      />
                    </div>
                  </section>
    
                  <section>
                    <h2 className="mb-9">Required Documents</h2>
    
                    <div className="grid grid-cols-4">
                      <div className="col-span-1 ml-6 ">
                        <ul className="text-sm list-disc">
                          <li>Company ID (Front & Back)</li>
                          <li>Latest Proof of Billing</li>
                          <li>Company Profile</li>
                          <li>SEC Registration</li>
                          <li>Business/Mayor’s Permit/BIR</li>
                          <li>3 Months latest bank statement</li>
                          <li>2 Valid ID of Representative</li>
                          <li>2 to 3 years In-house financial statement</li>
                          <li>2 to 3 years Audited financial statement</li>
                          <li>List of Cusotmers and Suppliers</li>
                          <li>List of Receivables and Payables</li>
                        </ul>
                      </div>
                      <div className="col-span-3">
                        <FilesDragAndDrop name="documents" />
                      </div>
                    </div>
                  </section>
    
                  {/* FILES PREVIEW */}
                  <section>
                    <FileTable tableHeader={tableHeaders}>
                      {/* {fileData.length > 0 ? (
                        fileData.map(({ file_name, size }, index) => (
                          <tr key={index}>
                            <SingleFileUploadCard
                              file_name={file_name}
                              size={size}
                            />
                          </tr>
                        ))
                      ) : (
                        <tr>
                          <td>Add Required Documents</td>
                        </tr>
                      )} */}
                    </FileTable>
                  </section>
                </main>
              </div>
            </>
          </Form>
        </FormikProvider>
      );
    }

  1. 这是我最近一直在使用的 headlessui 的下拉菜单
import { Fragment, useState } from "react";
import { Listbox, Transition } from "@headlessui/react";
import { CheckIcon, ChevronIcon } from "../ui/icons";

export default function ListBox({
  options,
  value,
  setValue,
  label,
  error,
  placeholder,
}) {
  return (
    <Listbox
      as="div"
      value={value}
      onChange={(val) => {
        setValue(val);
      }}
    >
      <div className="relative">
        <Listbox.Label className="label" htmlFor={label}>
          {label}
        </Listbox.Label>

        <Listbox.Button
          className={`relative w-full form-control 
           ${error && "error"} `}
        >
          <div className="flex items-center">
            <span
              className={`block truncate ${
                value ? "" : "text-base text-gray-400"
              } `}
            >
              {value || value.title || placeholder}
            </span>
          </div>
          <span className="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
            <ChevronIcon aria-hidden="true" />
          </span>
        </Listbox.Button>
        <Transition
          as={Fragment}
          leave="transition ease-in duration-100"
          leaveFrom="opacity-100"
          leaveTo="opacity-0"
        >
          <Listbox.Options className="absolute z-10 w-full py-1 mt-1 overflow-auto text-base bg-white rounded-md shadow-lg max-h-60 ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
            {options.map((item, index) => (
              <Listbox.Option
                key={index}
                className={({ active }) =>
                  `${active ? "text-forgot bg-green-100" : "text-gray-900"}
                              cursor-default select-none relative py-2 pl-10 pr-4`
                }
                value={item.title}
              >
                {({ selected, active }) => (
                  <>
                    <span
                      className={`${
                        selected && value ? "font-medium" : "font-normal"
                      } block truncate`}
                    >
                      {item.title}
                    </span>
                    {selected && value ? (
                      <span
                        className={`${active ? "text-forgot" : "text-forgot"}
                                    absolute inset-y-0 left-0 flex items-center pl-3`}
                      >
                        <CheckIcon className="w-5 h-5" aria-hidden="true" />
                      </span>
                    ) : null}
                  </>
                )}
              </Listbox.Option>
            ))}
          </Listbox.Options>
        </Transition>
      </div>
    </Listbox>
  );
}
  1. 这是当前客户的 api,具有包括实体在内的所有数据,我可以通过路由器查询获取 ID,这也是我获取 currentEntity
  2. 的地方
const { data: customer } = useSWR(
        id
          ? "/api/customer/" + id
          : null
      );
  1. 如何让 currentEntity 被 selected。 selectedEntity 是我存储的状态,它被作为下拉列表的列表框select编辑。
const currentEntity = customer?.summary?.type_entities?.find((val) => val.entity_name === selectedEntity)

希望我解释清楚了⊙﹏⊙非常需要你的帮助,我也是新手,还在学习一些东西。非常感谢您的帮助!谢谢。

问题已解决,但我不知道这是否是最佳方法。我刚刚添加了带有 enableReinitialize 的 formik 表单,以便在下拉值更改时更新初始值。