簡體   English   中英

state 數據無法使用 reactjs 中的 useState 設置

[英]state data can not be set using useState in reactjs

我有一個反應組件

import React from "react";
import { AgreementInfo } from "../../../../models/shop";
import { MdClose } from "react-icons/md";
import moment from "moment";
import { uploadImageCore } from "utils/image";

type AgreementInfoProps = {
  setFieldValue(agreement_code: string, val: AgreementInfo[]): void;
  kps: AgreementInfo[];
  index: number;
  kp: AgreementInfo;
};

export const Agreement = ({
  setFieldValue,
  kps,
  index,
  kp,
}: AgreementInfoProps): JSX.Element => {
  const [agreementCopy, setAgreementCopy] = React.useState("");

  const handleImageChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    console.log(e.currentTarget.files);
    const files = e.currentTarget.files ?? "";
    console.log({ files });
    const res = await uploadImageCore(files[0]);
    console.log({ res });
    const agreementInfos = [...kps];
    console.log({ agreementInfos });
    const newCopy = setAgreementCopy(res.data.data.url);
    console.log({ agreementCopy });
    console.log({ newCopy });
    agreementInfos[index].agreement_scan_copy = agreementCopy;
    setFieldValue("agreement_info", [...agreementInfos]);
  };

  return (
    <>
      <div className="grid grid-cols-2 gap-4 w-full">
        <div>
          <label className="block mr-4">
            <input
              placeholder="Agreement code"
              value={kp.agreement_code}
              className="block w-full form-input"
              onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
                const agreementInfos = [...kps];
                agreementInfos[index].agreement_code = e.target.value;
                setFieldValue("agreement_info", [...agreementInfos]);
              }}
            />
          </label>
        </div>

        <div>
          <label className="block mr-4">
            <input
              className="block w-full form-input"
              onChange={(e) => handleImageChange(e)}
              type="file"
            />
          </label>
        </div>

        <div>
          <label className="block">
            <input
              placeholder="Agreement Expairy Date"
              onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
                const agreementInfos = [...kps];
                agreementInfos[index].agreement_expiry_date = e.target.value;
                setFieldValue("agreement_info", [...agreementInfos]);
              }}
              type="date"
              value={moment(kp.agreement_expiry_date).format("YYYY-MM-DD")}
              className="block w-full form-input"
            />
          </label>
        </div>

        <div>
          <label className="block mr-4">
            <input
              placeholder="Credit Limit"
              value={kp.credit_limit}
              className="block w-full form-input"
              onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
                const agreementInfos = [...kps];
                agreementInfos[index].credit_limit = parseInt(e.target.value);
                setFieldValue("agreement_info", [...agreementInfos]);
              }}
            />
          </label>
        </div>

        <div>
          <label className="block mr-4">
            <input
              placeholder="Credit Time"
              value={kp.credit_time}
              className="block w-full form-input"
              onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
                const agreementInfos = [...kps];
                agreementInfos[index].credit_time = parseInt(e.target.value);
                setFieldValue("agreement_info", [...agreementInfos]);
              }}
            />
          </label>
        </div>
      </div>

      <button
        type="button"
        onClick={() =>
          setFieldValue(
            "agreement_info",
            kps.filter((_, kpIndex: number) => kpIndex !== index)
          )
        }
        className="p-2 ml-4 text-gray-500 rounded-full hover:bg-gray-600 hover:text-white"
      >
        <MdClose />
      </button>
    </>
  );
};

我想在 state agreementCopy副本中設置agreement_scan_copy掃描副本的數據。 但我無法在當前實現中傳遞數據。 Agreement組件將用於在另一個組件中以數組的形式顯示數據。 這是組件

import { FormikProps, FormikValues, Field } from "formik";
import "styled-components/macro";
import { KeyPerson } from "../../../../shop/component/create/KeyPerson";
import { Acquisition } from "../../../../shop/component/create/Acquisition";
import { Agreement } from "../../../../shop/component/create/Agreement";
import { CategoryHead } from "../../../../shop/component/create/CategoryHead";
import { BDM } from "../../../../shop/component/create/BDM";
import { KAM } from "../../../../shop/component/create/KAM";
import { VM } from "../../../../shop/component/create/VM";

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 default function AdditionalInformations({
  formikBag,
}: {
  formikBag: FormikProps<FormikValues>;
}): JSX.Element {
  return (
    <div className="py-10 px-6">
      <div className="flex flex-row justify-between">
        <div className="mb-6">
          <>
            <div className="grid grid-cols-2 gap-4 w-full">
              <div className="mb-6">
                <label htmlFor={"organisation_type"}>
                  {"Organization Type"}
                </label>
                <Field
                  as="select"
                  name="organisation_type"
                  className="form-select"
                >
                  <option value="small">Small</option>
                  <option value="medium">Medium</option>
                  <option value="large">Large</option>
                </Field>
              </div>
              <div className="mb-6">
                <label htmlFor={"bin_no"}>{"BIN No"}</label>
                <Field
                  type="number"
                  name="bin_no"
                  id="bin_no"
                  className={"form-input"}
                />
              </div>
              <div className="mb-6">
                <label htmlFor={"trade_license_no"}>{"Trade License No"}</label>
                <Field
                  type="text"
                  name="trade_license_no"
                  id="trade_license_no"
                  className={"form-input"}
                />
              </div>
            </div>

            <div className="block mb-6">
              <p className="mb-2">
                Key Personnel
                <button
                  type="button"
                  onClick={() =>
                    formikBag.setFieldValue("key_personnel", [
                      ...formikBag.values.key_personnel,
                      {
                        username: "",
                        designation: "",
                        phone_no: "",
                        email: "",
                      },
                    ])
                  }
                  className="float-right ml-4 text-sm underline"
                >
                  Add Key Personnel
                </button>
              </p>
              {formikBag.values.key_personnel.map(
                (
                  kp: {
                    username: string;
                    designation: string;
                    phone_no: string;
                    email: string;
                  },
                  index: number
                ) => (
                  <div
                    key={index}
                    className="flex items-center p-4 mt-2 bg-gray-100 rounded"
                  >
                    <KeyPerson
                      setFieldValue={formikBag.setFieldValue}
                      kps={formikBag.values.key_personnel}
                      index={index}
                      kp={kp}
                    />
                  </div>
                )
              )}
            </div>

            <div className="grid grid-cols-2 gap-4 w-full">
              <div className="block mb-6">
                <p className="mb-2">
                  <b>Category Head</b>
                  <button
                    type="button"
                    onClick={() =>
                      formikBag.setFieldValue("category_head", [
                        ...formikBag.values.category_head,
                        {
                          username: "",
                        },
                      ])
                    }
                    className="float-right ml-4 text-sm underline"
                  >
                    Add Category Head
                  </button>
                </p>
                {formikBag.values.category_head.map(
                  (
                    ch: {
                      username: string;
                    },
                    index: number
                  ) => (
                    <div
                      key={index}
                      className="flex items-center p-4 mt-2 bg-gray-100 rounded"
                    >
                      <CategoryHead
                        setFieldValue={formikBag.setFieldValue}
                        chs={formikBag.values.category_head}
                        index={index}
                        ch={ch}
                      />
                    </div>
                  )
                )}
              </div>
              <div className="block mb-6">
                <p className="mb-2">
                  <b>BDM</b>
                  <button
                    type="button"
                    onClick={() =>
                      formikBag.setFieldValue("bdm", [
                        ...formikBag.values.bdm,
                        {
                          username: "",
                        },
                      ])
                    }
                    className="float-right ml-4 text-sm underline"
                  >
                    Add BDM
                  </button>
                </p>
                {formikBag.values.bdm.map(
                  (
                    bdm: {
                      username: string;
                    },
                    index: number
                  ) => (
                    <div
                      key={index}
                      className="flex items-center p-4 mt-2 bg-gray-100 rounded"
                    >
                      <BDM
                        setFieldValue={formikBag.setFieldValue}
                        bdms={formikBag.values.bdm}
                        index={index}
                        bdm={bdm}
                      />
                    </div>
                  )
                )}
              </div>
              <div className="block mb-6">
                <p className="mb-2">
                  <b>KAM</b>
                  <button
                    type="button"
                    onClick={() =>
                      formikBag.setFieldValue("kam", [
                        ...formikBag.values.kam,
                        {
                          username: "",
                        },
                      ])
                    }
                    className="float-right ml-4 text-sm underline"
                  >
                    Add KAM
                  </button>
                </p>
                {formikBag.values.kam.map(
                  (
                    kam: {
                      username: string;
                    },
                    index: number
                  ) => (
                    <div
                      key={index}
                      className="flex items-center p-4 mt-2 bg-gray-100 rounded"
                    >
                      <KAM
                        setFieldValue={formikBag.setFieldValue}
                        kams={formikBag.values.kam}
                        index={index}
                        kam={kam}
                      />
                    </div>
                  )
                )}
              </div>
              <div className="block mb-6">
                <p className="mb-2">
                  <b>VM</b>
                  <button
                    type="button"
                    onClick={() =>
                      formikBag.setFieldValue("vm", [
                        ...formikBag.values.vm,
                        {
                          username: "",
                        },
                      ])
                    }
                    className="float-right ml-4 text-sm underline"
                  >
                    Add VM
                  </button>
                </p>
                {formikBag.values.vm.map(
                  (
                    vm: {
                      username: string;
                    },
                    index: number
                  ) => (
                    <div
                      key={index}
                      className="flex items-center p-4 mt-2 bg-gray-100 rounded"
                    >
                      <VM
                        setFieldValue={formikBag.setFieldValue}
                        vms={formikBag.values.vm}
                        index={index}
                        vm={vm}
                      />
                    </div>
                  )
                )}
              </div>
            </div>

            <div className="block mb-6">
              <p className="mb-2">
                Acquisition Info
                <button
                  type="button"
                  onClick={() =>
                    formikBag.setFieldValue("acquisition_info", [
                      ...formikBag.values.acquisition_info,
                      {
                        acquisition_code: "",
                        acquisition_by: "",
                        acquisition_phone_no: "",
                        acquisition_email: "",
                        acquisition_date: "",
                      },
                    ])
                  }
                  className="float-right ml-4 text-sm underline"
                >
                  Add Acquisition Info
                </button>
              </p>
              {formikBag.values.acquisition_info.map(
                (
                  kp: {
                    acquisition_code: string;
                    acquisition_by: string;
                    acquisition_phone_no: string;
                    acquisition_email: string;
                    acquisition_date: string;
                  },
                  index: number
                ) => (
                  <div
                    key={index}
                    className="flex items-center p-4 mt-2 bg-gray-100 rounded"
                  >
                    <Acquisition
                      setFieldValue={formikBag.setFieldValue}
                      kps={formikBag.values.acquisition_info}
                      index={index}
                      kp={kp}
                    />
                  </div>
                )
              )}
            </div>

            <div className="block mb-6">
              <p className="mb-2">
                Agreement Info
                <button
                  type="button"
                  onClick={() =>
                    formikBag.setFieldValue("agreement_info", [
                      ...formikBag.values.agreement_info,
                      {
                        agreement_code: "",
                        agreement_scan_copy: "",
                        agreement_expiry_date: "",
                        credit_limit: "",
                        credit_time: "",
                      },
                    ])
                  }
                  className="float-right ml-4 text-sm underline"
                >
                  Add Agreement Info
                </button>
              </p>
              {formikBag.values.agreement_info.map(
                (
                  kp: {
                    agreement_code: string;
                    agreement_scan_copy: string;
                    agreement_expiry_date: string;
                    credit_limit: number;
                    credit_time: number;
                  },
                  index: number
                ) => (
                  <div
                    key={index}
                    className="flex items-center p-4 mt-2 bg-gray-100 rounded"
                  >
                    <Agreement
                      setFieldValue={formikBag.setFieldValue}
                      kps={formikBag.values.agreement_info}
                      index={index}
                      kp={kp}
                    />
                  </div>
                )
              )}
            </div>

            <div className="grid grid-cols-2 gap-4 w-full">
              <div>
                <label htmlFor={"bank_account_name"}>
                  {"Bank Account Name"}
                </label>
                <Field
                  type="text"
                  name="bank_account_name"
                  id="bank_account_name"
                  className={"form-input"}
                />
              </div>

              <div>
                <label htmlFor={"bank_account_no"}>{"Bank Account No"}</label>
                <Field
                  type="number"
                  name="bank_account_no"
                  id="bank_account_no"
                  className={"form-input"}
                />
              </div>

              <div>
                <label htmlFor={"bank_name"}>{"Bank Name"}</label>
                <Field
                  type="text"
                  name="bank_name"
                  id="bank_name"
                  className={"form-input"}
                />
              </div>

              <div>
                <label htmlFor={"bank_branch_name"}>{"Bank Branch Name"}</label>
                <Field
                  type="text"
                  name="bank_branch_name"
                  id="bank_branch_name"
                  className={"form-input"}
                />
              </div>

              <div>
                <label htmlFor={"bank_branch_routing_no"}>
                  {"Bank Branch Routing No"}
                </label>
                <Field
                  type="number"
                  name="bank_branch_routing_no"
                  id="bank_branch_routing_no"
                  className={"form-input"}
                />
              </div>

              <div>
                <label htmlFor={"sbu_unit"}>{"SBU Unit"}</label>
                <Field
                  type="text"
                  name="sbu_unit"
                  id="sbu_unit"
                  className={"form-input"}
                />
              </div>
            </div>
          </>
        </div>
      </div>
    </div>
  );
}

所以Agreement數組的數據結構是

{
  agreement_code: "",
  agreement_scan_copy: "",
  agreement_expiry_date: "",
  credit_limit: "",
  credit_time: "",
}

所以現在我想從Agreement組件中設置agreement_scan_copy掃描復制鍵中的數據,然后在 API 中進行 POST。 但是上面的代碼並沒有設置數組中的值。 這些是控制台日志

FileList {0: File, length: 1}
0: File
lastModified: 1618304176889
lastModifiedDate: Tue Apr 13 2021 14:56:16 GMT+0600 (Bangladesh Standard Time) {}
name: "ehealth.png"
size: 4276
type: "image/png"
webkitRelativePath: ""
__proto__: File
length: 1
__proto__: FileList

res:
config: {url: "https://api-dev.evaly.com.bd/core/image/upload", method: "post", data: FormData, headers: {…}, transformRequest: Array(1), …}
data:
data:
url: "https://s3-ap-southeast-1.amazonaws.com/media.evaly.com.bd/media/images/d26acdb48506-ehealth.png"
url_sm: "https://df17fp68uwcso.cloudfront.net/eyJidWNrZXQiOiAibWVkaWEuZXZhbHkuY29tLmJkIiwgImtleSI6ICJtZWRpYS9pbWFnZXMvZDI2YWNkYjQ4NTA2LWVoZWFsdGgucG5nIiwgImVkaXRzIjogeyJyZXNpemUiOiB7IndpZHRoIjogMTUwLCAiaGVpZ2h0IjogMTUwLCAiZml0IjogImNvbnRhaW4ifSwgImJhY2tncm91bmQiOiB7InIiOiAyNTUsICJnIjogMjU1LCAiYiI6IDI1NSwgImFscGhhIjogMX0sICJmbGF0dGVuIjogdHJ1ZSwgImpwZWciOiB7InF1YWxpdHkiOiA3NX19fQ=="
__proto__: Object
message: "Image upload successful"
success: true
__proto__: Object
headers: {content-length: "551", content-type: "application/json"}
request: XMLHttpRequest {readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, onreadystatechange: ƒ, …}
status: 201
statusText: "Created"
__proto__: Object
__proto__: Object

agreementInfos: Array(2)
0:
agreement_code: "ert8909"
agreement_expiry_date: "2021-06-05"
agreement_scan_copy: ""
credit_limit: 20
credit_time: 5
__proto__: Object
1:
agreement_code: "tyu3456"
agreement_expiry_date: "2021-06-05"
agreement_scan_copy: ""
credit_limit: 30
credit_time: 15
__proto__: Object
length: 2
__proto__: Array(0)
__proto__: Object

agreementCopy: ""

newCopy: undefined

如何在agreementInfos信息數組中設置agreement_scan_copy掃描復制圖像數據?

uploadImageCore 組件在這里

export async function uploadImageCore(file: any) {
  const form = new FormData();
  form.append("image", file, file.name);
  try {
    const apiUrl = baseUrl.URL_CORE + "/image/upload";
    const res = await axios.post(apiUrl, form, {
      headers: {
        Authorization: "Bearer " + getTokenFromCookies(), //the token is a variable which holds the token
      },
    });

    if (equals(res.status, 201)) {
      return Promise.resolve(res);
    } else {
      return Promise.reject();
    }
  } catch (error) {
    // console.log(error);

    return Promise.reject(error.response.data);
  }
}

為什么在這里需要 state? 你不能只做agreementInfos[index].agreement_scan_copy = res.data.data.url; ?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM