Сохранять данные определенным образом

#javascript #reactjs

#javascript #reactjs

Вопрос:

У меня есть приложение, в котором пользователь должен вводить данные об этом, и после их сохранения form данные должны быть выведены в определенной форме.

 const ParrentForm = () => {
  const [carNr, setCarNr] = useState([]);

  const onFinish = (values) => {
    const { firstName, lastName } = values;
    const user = {
      firstName,
      lastName,
      things: {
        cars: []
      }
    };
    console.log(user);
  };

  const onFinishFailed = (errorInfo) => {
    console.log("Failed:", errorInfo);
  };
  const setFloorsNrHandler = (nr) => {
    setCarNr(Array.from({ length: nr }, (v, k) => k));
  };

  return (
    <div>
      <Form
        name="main"
        initialValues={{ remember: true }}
        onFinish={onFinish}
        onFinishFailed={onFinishFailed}
      >
        <Form.Item
          label="First Name"
          name="firstName"
          rules={[{ required: true, message: "Please input your first name!" }]}
        >
          <Input />
        </Form.Item>
        <Form.Item
          label="Last Name"
          name="lastName"
          rules={[{ required: true, message: "Please input your last name!" }]}
        >
          <Input />
        </Form.Item>
        <Form.Item
          name="nrOfCars"
          label="Cars"
          rules={[{ type: "number", min: 0, max: 15 }]}
        >
          <InputNumber onChange={setFloorsNrHandler} />
        </Form.Item>
        {carNr.map((f, k) => {
          return (
            <Form.Item key={k}>
              <InnerForm cKey={k} />
            </Form.Item>
          );
        })}
        <Form.Item>
          <Button type="primary" htmlType="submit">
            Submit
          </Button>
        </Form.Item>
      </Form>
    </div>
  );
};

export default ParrentForm;  

Ожидаемые данные должны выглядеть следующим образом:

 {
  "user": {
    "firstName": "Bill",
    "lastName": "M.",
  },
  "things": {
    "cars": [
      {
        "nr":  1,
        "carsList": [
          {
            "name": "Car 1",
            "nr": 1
          },
            {
            "name": "Audi",
            "nr": 2
          },
          ,
            {
            "name": "Mercedes",
            "nr": 3
          }
        ]
      },
      {
        "nr":  2,
        "carsList": [
          {
            "name": "Bmw",
            "nr": 1  
          }
        ]
      }
    ]
  }
}  

Как изменить данные внутри onFinish функции, чтобы получить приведенный выше результат?

демонстрация:https://codesandbox.io/s/modest-cache-o0g65?file=/OuterForm.js:136-1755

Ответ №1:

Сначала вам нужно уничтожить (doc) объект значений формы, объединенный с оператором распространения (doc), чтобы получить значения, связанные с автомобилем (я сохранил в переменной carValues ). После этого единственное, что осталось сделать, это манипулировать с этой переменной, здесь я объединил использование Object.entries и Array.prototype.map

Есть часть с Number(key) , потому что Object.entries() преобразует объект в массив пары ключ-значение с типом ключа string, поэтому вам нужно сначала привести его к Number индексу на основе 1

 const onFinish = values => {
  const { firstName, lastName, nrOfCars, ...carValues } = values
  const cars = Object.entries(carValues).map(([key, value]) => ({
    nr: Number(key)   1,
    carsList: (value.cars || []).map((car, carIndex) => ({
      nr: carIndex   1,
      name: car.name
    }))
  }))
  const user = {
    firstName,
    lastName,
    things: {
      cars
    }
  }
  console.log(JSON.stringify(user, null, 2))
}

  

Разветвленный codesandbox для реализации

Редактирование отполировано-rain-w3cxw

Комментарии:

1. почему, если я добавляю дополнительный <ввод> во внешней форме, например: <Form.Item label="pasword" name="pasword" rules={[{ required: true, message: "Please input your password" }]} > <Input /> </Form.Item> , я получаю сообщение об ошибке: TypeError: Cannot read property 'map' of undefined ..?

2. @AskMen мой плохой для случая, когда не добавляются никакие автомобили, пожалуйста, измените carsList: value.cars. на carsList: (value.cars || []). . Обновленный ответ также

3. делая это, я получаю в качестве последнего элемента: { «nr»: null, «carsList»: [] } вы знаете, почему?

4. не могли бы вы помочь?

5. @AskMen Я пробовал в своей изолированной среде и не вижу проблем, не могли бы вы предоставить шаги, которые воспроизводят ваше неожиданное поведение, а также обновленную ссылку на изолированную среду?