我如何才能根据选择的产品传递产品 ID?

How would I be able to pass the product ID according to what product was selected?

我有一个动态表单,用户可以在其中添加多个产品。我想知道如何保存所选产品的 ID。

console.log(fields, "fields");中,这是我可以看到保存的产品的地方。那么如何保存选定的产品 ID?

如有任何帮助,我们将不胜感激。谢谢。

Codesandbox:https://codesandbox.io/s/react-hook-form-wizard-form-from-reddit-with-data-ouy64e?file=/src/fieldArray.js:322-4143

const products = [
  {
    prodName: "Tumbler",
    price: 1.5,
    size: "500",
    colorMap: { Black: 20, Pink: 10, Green: 5 },
    id: "aRLMZkiSU7T0lcsPCSsV"
  },
  {
    prodName: "Shirt",
    price: 2.0,
    size: "L",
    colorMap: { Blue: 10, Black: 10 },
    id: "uTHIR6OQFRuqP9Drft0e"
  },
  {
    size: "200",
    price: 2.0,
    colorMap: { Green: 50, Red: 19, Black: 20 },
    prodName: "Notebook",
    id: "y9ECyZBKp2OBekmWym4M"
  }
];

const options = products.map(
  (object) =>
    object.prodName +
    " - " +
    object.size +
    `${object.cat === "CM" || object.cat === "ML" ? "- " + object.cat : ""}` +
    " "
);

console.log(options, "options");

const FieldArray = ({ control, register, setValue, getValues }) => {
  const { fields, append, remove, prepends } = useFieldArray({
    control,
    name: "order"
  });

  console.log(fields, "fields");

  renderCount++;

  return (
    <div>
      <ul>
        {fields.map((item, index) => {
          console.log(item);
          return (
            <li key={item.id}>
              <Controller
                control={control}
                name={`order.${index}.product`}
                render={({ field: { onChange, value = "", ...rest } }) => (
                  <Autocomplete
                    {...rest}
                    onInputChange={(e, newValue) => {
                      onChange(newValue);
                      console.log(newValue, "new value");
                    }}
                    inputValue={value}
                    options={products}
                    // isOptionEqualToValue={(option, value) =>
                    //   option?.value === value?.value
                    // }
                    getOptionLabel={(option) =>
                      option.prodName + " " + option.size
                    }
                    // getOptionLabel={(option) => option?.label ?? ""}
                    renderInput={(params) => (
                      <TextField
                        {...params}
                        label="Product"
                        variant="outlined"
                        fullWidth
                      />
                    )}
                  />
                )}
              />

          );
        })}
    </div>
  );
};

export default FieldArray;

更新

这是step1.js

中的提交按钮
const onSubmit = (data) => {
    // action(data);
    console.log(data, "d");
    const newOrder = [];
    data.order.forEach(({ product, variation }) => {
      const newVariantion = [];
      variation.forEach(({ qty, color }) => {
        newVariantion.push({ qty: parseInt(qty), color });
      });
      newOrder.push({ product, variation: newVariantion });
    });

    actions.updateAction(data);
    console.log(newOrder, "new order");
    navigate("/step2", newOrder);
  };

更新: 我如何才能将产品 ID 推送到 newOrder 与所选产品的 productID 相匹配的位置?

根据 的回答进行了一些改进:

您始终可以为第一个产品添加 useState(保存整个产品,而不仅仅是一个 ID),然后通过 onChange 管理所有内容:

import {useState} from 'react';

/*...something here...*/
const FieldArray = ({ control, register, setValue, getValues }) => {
  const [prod, setProd] = useState({0: product[0]});
  /*...something here...*/
  {fields.map((item, index) => {
    /*...something here...*/
    <Autocomplete
      onChange={(e, v)=>{console.log(v); setProd({...prod, [index]:v});}}
      value={prod[index] || {}}
      options={products}
      /*...other stuff here...*/

查看 onChange 中的 console.log(v) 中可用的内容。

另请查看 inputValuevalue here 之间的区别。

更新

如果您需要保存多个产品 - prod 必须是一个对象,其键代表“字段”项。例如,像这样的 {0: prod1, 1: prod3, 2: prod11}。然后 value 使用 prod[index] 并适当更改 setter。 (我已经为这种情况编辑了上面的代码)。有多种方法可以做到这一点 - 这只是我想到的一种方法。

更新 2:

我不知道你在onSubmit中到底想要什么,所以这里有一个想法,你把它改成你想要的。

Step1.onSubmit中你可以做这样的事情:

// forEach 2nd argument is an index (counter) 
data.order.forEach(({ product, variation }, indx) => {
  // some code
  newOrder.push({ product, variation: newVariantion, prod: prod[indx] });
  // more code
}