Javascript 将状态值传递给props,然后将props从reactjs中的子组件传递给父组件

Javascript 将状态值传递给props,然后将props从reactjs中的子组件传递给父组件,javascript,reactjs,state,react-props,Javascript,Reactjs,State,React Props,我有一个反应组件 /* eslint-disable react/prop-types */ import { useQuery } from "react-query"; import { FormikProps, FormikValues, Field } from "formik"; import { createFormModel, IfieldObject } from "../create/formik/CreateModel&quo

我有一个反应组件

/* eslint-disable react/prop-types */
import { useQuery } from "react-query";
import { FormikProps, FormikValues, Field } from "formik";
import { createFormModel, IfieldObject } from "../create/formik/CreateModel";
import {
  Combobox,
  ComboboxInput,
  ComboboxOptionText,
  ComboboxPopover,
  ComboboxOption,
  ComboboxList,
} from "@reach/combobox";
import { getActiveMerchants } from "../../../../../request/shop";
import { useState } from "react";
import "styled-components/macro";
import Loader from "react-spinners/BarLoader";
import { useDebounce } from "use-debounce";
import ImageUploadCrop from "../../../../../common/ImageUploadCrop";
import MapViewWithSearch from "../../../../../common/MapViewWithSearch";

export const inputClass =
  "rounded bg-gray-100 px-2 py-2 focus:bg-white border border-gray-100 focus:border-black block w-full";

export const arrowIcon = `data:image/svg+xml;utf8,<svg width='15' height='7' viewBox='0 0 15 7' fill='none' xmlns='http://www.w3.org/2000/svg'>
<path fill-rule='evenodd' clip-rule='evenodd' d='M7.59952 7C7.37152 7 7.14452 6.923 6.95952 6.768L0.959518 1.768C0.535518 1.415 0.477518 0.784 0.831518 0.36C1.18452 -0.0640001 1.81452 -0.121 2.23952 0.232L7.61052 4.708L12.9725 0.393C13.4025 0.047 14.0325 0.115 14.3785 0.545C14.7245 0.975 14.6565 1.604 14.2265 1.951L8.22652 6.779C8.04352 6.926 7.82152 7 7.59952 7Z' fill='gray'/>
</svg>`;

export function BasicInformation({
  formikBag,
}: {
  formikBag: FormikProps<FormikValues>;
}): JSX.Element {
  const {
    name,
    logo_image,
    image,
    address,
    latitude,
    longitude,
    contact_number,
  }: IfieldObject = createFormModel;

  const [searchMerchantText, setSearchMerchantText] = useState<string>("");
  const [selectedMerchant, setSelectedMerchant] = useState<{
    merchant_name: string;
    merchant_code: string;
  }>({ merchant_name: "", merchant_code: "" });
  const [throttledMerchantText] = useDebounce(searchMerchantText, 500);
  const queryMerchantSearch = useQuery(
    ["merchant-search", throttledMerchantText],
    () => getActiveMerchants(`name=${searchMerchantText}&limit=10&page=1`),
    {
      enabled: Boolean(throttledMerchantText),
    }
  );

  const merchants = queryMerchantSearch?.data?.data?.data?.merchants ?? [];

  console.log({ selectedMerchant });

  return (
    <div className="py-10 px-6">
      <form>
        <div className="flex items-center">
          <div className="mb-6">
            <ImageUploadCrop
              title={logo_image?.label}
              setFieldValue={(value: string) =>
                formikBag.setFieldValue("logo_image", value)
              }
              logo={formikBag.values.logo_image}
            />
            {formikBag.errors.logo_image && (
              <p className="text-red-500">{formikBag.errors.logo_image}</p>
            )}
          </div>

          <div className="ml-6 mb-6">
            <ImageUploadCrop
              title={image?.label}
              setFieldValue={(value: string) =>
                formikBag.setFieldValue("image", value)
              }
              logo={formikBag.values.image}
            />
            {formikBag.errors.image && (
              <p className="text-red-500">{formikBag.errors.image}</p>
            )}
          </div>
        </div>
        <div className="grid grid-cols-2 gap-4 w-full">
          <div className="mb-6">
            <label htmlFor={"name"}>{name?.label}</label>
            <Field
              type="text"
              name="name"
              placeholder="Name"
              id={"name"}
              className={"form-input"}
            />
            {formikBag.errors.name && (
              <p className="text-red-500">{formikBag.errors.name}</p>
            )}
          </div>

          <div className="mb-6">
            <div>
              <Combobox>
                <label className="relative block mb-2">
                  <p>Merchant Name*</p>
                  <ComboboxInput
                    placeholder="Search Merchant ..."
                    className="form-input"
                    name="merchant_code"
                    onChange={(e: any) => {
                      // formikBag.handleChange(e.target.value);
                      setSearchMerchantText(e.target.value);
                    }}
                  />
                  {/* {formikBag.errors.merchant_code &&
                              formikBag.touched.merchant_code && (
                                <p className="text-red-500">
                                  {formikBag.errors.merchant_code}
                                </p>
                              )} */}
                </label>

                {Array.isArray(merchants) && (
                  <ComboboxPopover
                    portal={false}
                    className="absolute bg-white border w-auto"
                    css={`
                      z-index: 2001;
                    `}
                  >
                    {queryMerchantSearch.isLoading ? (
                      <div className="flex items-center justify-center p-4">
                        <Loader />
                      </div>
                    ) : merchants.length > 0 ? (
                      <ComboboxList className="bg-white shadow-md ">
                        {merchants.map((merchant, idx: number) => {
                          return (
                            <div key={idx} className="p-2 hover:bg-gray-100">
                              <div className="flex items-center">
                                <ComboboxOption
                                  value={merchant.merchant_name}
                                  className="w-full text-xs cursor-pointer"
                                  onClick={() => {
                                    setSelectedMerchant({
                                      merchant_name: merchant.merchant_name,
                                      merchant_code: merchant.merchant_code,
                                    });
                                  }}
                                >
                                  <ComboboxOptionText /> -{" "}
                                  <span className="capitalize font-semibold">
                                    {merchant.merchant_type}
                                  </span>
                                </ComboboxOption>
                              </div>
                            </div>
                          );
                        })}
                      </ComboboxList>
                    ) : (
                      <div className="flex items-center justify-center p-8">
                        {throttledMerchantText
                          ? "No results found"
                          : "Type merchant code ..."}
                      </div>
                    )}
                  </ComboboxPopover>
                )}
              </Combobox>
            </div>
          </div>
        </div>

        <div className="mb-6">
          <label htmlFor="description">Description</label>
          <Field
            type="text"
            name="description"
            as={"textarea"}
            id={"description"}
            className={"form-input"}
          />
        </div>

        <div className="mb-6">
          <label htmlFor={"address"}>{address?.label}</label>
          <Field
            type="text"
            name="address"
            id="address"
            className={"form-input"}
          />
          {formikBag.errors.address && (
            <p className="text-red-500">{formikBag.errors.address}</p>
          )}
        </div>

        <div className="grid grid-cols-2 gap-4 w-full">
          <div className="mb-6">
            <label htmlFor={"latitude"}>{latitude?.label}</label>
            <Field
              type="number"
              name="latitude"
              id="latitude"
              className={"form-input"}
            />
            {formikBag.errors.latitude && (
              <p className="text-red-500">{formikBag.errors.latitude}</p>
            )}
          </div>

          <div className="mb-6">
            <label htmlFor={"longitude"}>{longitude?.label}</label>
            <Field
              type="number"
              name="longitude"
              id="longitude"
              className={"form-input"}
            />
            {formikBag.errors.longitude && (
              <p className="text-red-500">{formikBag.errors.longitude}</p>
            )}
          </div>
        </div>

        <div className="mb-6">
          <MapViewWithSearch
            lat={
              formikBag.values.latitude ? formikBag.values.latitude : 23.777176
            }
            address={formikBag.values.address}
            lng={
              formikBag.values.longitude
                ? formikBag.values.longitude
                : 90.399452
            }
            onChangeAddress={(lat, lng, address) => {
              formikBag.setFieldValue("address", address);
              formikBag.setFieldValue("latitude", lat);
              formikBag.setFieldValue("longitude", lng);
            }}
          />
        </div>

        <div className="grid grid-cols-2 gap-4 w-full">
          <div className="mb-6">
            <label htmlFor={"longitude"} className="block">
              {contact_number?.label}
            </label>
            <input
              name="contact_number"
              type="text"
              value={formikBag.values.contact_number}
              onChange={formikBag.handleChange}
              maxLength={11}
              className={inputClass}
              placeholder="01xxxxxx"
              pattern="[0-9]+"
            />
            {formikBag?.errors?.contact_number ? (
              <small className="text-red-600">
                {formikBag?.errors?.contact_number}
              </small>
            ) : null}
          </div>

          <div className="mb-6">
            <label htmlFor={"shop_type"}>{"Shop Type"}</label>
            <Field as="select" name="shop_type" className="form-select">
              <option value="regular">Regular</option>
              <option value="campaign">Campaign</option>
              <option value="express">Express</option>
            </Field>
          </div>
        </div>
        <div className="grid grid-cols-2 gap-4 w-full">
          <div className="mb-4" role="group">
            <p className="block mb-2">Is Delivery Hero Allowed</p>
            <label className="mr-4">
              <input
                name="is_delivery_hero_allowed"
                type="radio"
                checked={!formikBag.values.is_delivery_hero_allowed}
                onChange={() => {
                  formikBag.setFieldValue("is_delivery_hero_allowed", false);
                }}
                value="false"
              />{" "}
              <span className="ml-2">No</span>
            </label>
            <label>
              <input
                name="is_delivery_hero_allowed"
                type="radio"
                checked={formikBag.values.is_delivery_hero_allowed}
                onChange={() =>
                  formikBag.setFieldValue("is_delivery_hero_allowed", true)
                }
                value="true"
              />{" "}
              <span className="ml-2">Yes</span>
            </label>
          </div>
          <div className="mb-4" role="group">
            <p className="block mb-2">Is Cash On Delivery Allowed</p>
            <label className="mr-4">
              <input
                name="is_cod_allowed"
                type="radio"
                checked={!formikBag.values.is_cod_allowed}
                onChange={() => {
                  formikBag.setFieldValue("is_cod_allowed", false);
                }}
                value="false"
              />{" "}
              <span className="ml-2">No</span>
            </label>
            <label>
              <input
                name="is_cod_allowed"
                type="radio"
                checked={formikBag.values.is_cod_allowed}
                onChange={() => formikBag.setFieldValue("is_cod_allowed", true)}
                value="true"
              />{" "}
              <span className="ml-2">Yes</span>
            </label>
          </div>
        </div>
      </form>
    </div>
  );
}
因此,我想在
行中传递
selectedMerchant
道具,如
我试图在道具中添加状态,如

export function BasicInformation({
  formikBag,
  selectedMerchant,
}: {
  formikBag: FormikProps<FormikValues>;
  selectedMerchant: any;
}): JSX.Element {
-------- 
}
导出函数基本信息({
formikBag,
精选的麦肯特,
}: {
formikBag:FormikProps;
selectedMerchant:任何;
}):JSX.Element{
-------- 
}
并传递像
这样的道具,但这会给我带来错误


注意:在这个项目中,我将无法使用任何类型的状态管理工具,如Redux。

通常道具从父级流向子级,而不是oposite。@litelite那么我该怎么办?
export function BasicInformation({
  formikBag,
  selectedMerchant,
}: {
  formikBag: FormikProps<FormikValues>;
  selectedMerchant: any;
}): JSX.Element {
-------- 
}