Динамически изменять значение в Formik при изменении состояния

Мне нужно менять значение в полях формы каждый раз, когда изменяется состояние (называемое selectedProduct, его поле ввода не включено в тег Formik). Я старался:

  1. помещая значение, которое я хочу, в initialValues ​​​​(очевидно, не работает, потому что при первом рендеринге я еще не выбрал свой selectedProduct)
  2. помещая значение, которое я хочу, в реквизиты значения в каждом поле в formik. Это почти работает: Datepicker получает правильное значение, ввод в поле выбора не получает никакого значения (не знаю, почему), текстовое поле принимает правильное значение, но это закрыто меткой. И это потому, что ни одно из полей не проверяется.

Это то, что я сделал, применив два пункта выше

import React, { useState } from 'react';
import * as Yup from 'yup';
import {
  Formik, Form, ErrorMessage, Field,
} from 'formik';
import {
  Button, TextField,
  MenuItem,
} from '@material-ui/core';
import DateFnsUtils from '@date-io/date-fns';
import {
  MuiPickersUtilsProvider,
  KeyboardDatePicker,
} from '@material-ui/pickers';

const validationSchema = Yup.object().shape({
  startValidityDate: Yup.date().required(),
  discount: Yup.string().required(),
  days: Yup.string().required(),
});

const MyComponent = ({filteredProduct, daysList}) => {

   const [selectedProduct, setSelectedProduct] = useState('');

   const onChangeProduct = (product) => {
      setSelectedProduct(product.target.value);
   };

  const handleRunButton = (newExecution) => {
     console.log(newExecution);
  };

   return (
      <div>
          <div className={classes.productComboWrapper}>
             <div id="selectBoxNotIncludedInFormik">
                <TextField
                   margin="normal"
                   style={{}}
                   variant="outlined"
                   name="productId"
                   id="productId"
                   fullWidth
                   select
                   label="Select product"
                   value={selectedProduct?.id}
                   onChange={(product) => onChangeProduct(product)}
                >

                   <MenuItem key="" value="">
                      {StringsConst.noneSelected}
                   </MenuItem>
                   {filteredProduct?.map((el) => (
                      <MenuItem key={el} value={el}>
                         {el.isin}
                      </MenuItem>
                   ))}
               </TextField>
            </div>
         </div>

         <Formik
            initialValues={{
               startValidityDate: selectedProduct?.startValidityDate,
               days: selectedProduct?.coupon?.days,
               discount: selectedProduct?.discount,
            }}
            validationSchema={validationSchema}
            onSubmit={(values) => {
               const newExecution = {
                  startValidityDate: values.startValidityDate,
                  days: values.days,
                  discount: values.discount,
               };
               handleRunButton(newExecution);
            }}
         >
            {({
               errors, dirty, setFieldValue, values,
            }) => (
               <Form>
                  <div className={classes.datePicker}>
                     <MuiPickersUtilsProvider utils={DateFnsUtils}>
                        <KeyboardDatePicker
                           disableToolbar
                           label="Start Validity Date"
                           inputVariant="outlined"
                           variant="inline"
                           autoOk
                           fullWidth
                           disabled
                           format="dd/MM/yyyy"
                           value={selectedProduct?.startValidityDate}
                           onChange={(dt) => setFieldValue('startValidityDate', dt)}
                           KeyboardButtonProps={{
                             'aria-label': 'change date',
                           }}
                       />
                   </MuiPickersUtilsProvider>
                 </div>

                 <div className={classes.fieldWrapper}>
                    <Field
                       className={classes.field}
                       name="discount"
                       as={TextField}
                       variant="outlined"
                       margin="normal"
                       fullWidth
                       id="discount"
                       autoComplete="discount"
                       placeholder="Discount"
                       disabled
                       value={selectedProduct?.discount}
                    />
                  </div>

                 <div className={classes.textFieldWrapper}>

                    <TextField
                        margin="normal"
                        style={{}}
                        variant="outlined"
                        name="days"
                        id="days"
                        fullWidth
                        select
                        label="Days"
                        disabled
                        value={selectedProduct?.coupon?.days}
                        onChange={(val) => setFieldValue('days', val.target.value)}
                    >

                       <MenuItem key="" value="">
                          {StringsConst.noneSelected}
                       </MenuItem>
                       {daysList.map((el) => (
                          <MenuItem key={el} value={el}>
                             {el}
                          </MenuItem>
                       ))}
                    </TextField>
           
                 </div>

                  <div className={classes.buttonContainer}>
                     <Button
                        type="submit"
                        fullWidth
                        variant="contained"
                        color="primary"
                        className={classes.submit}
                     >
                         {StringsConst.Run}
                     </Button>
                  </div>
        
              </Form>
           )}
        </Formik>

      </div>
   )

}

Итак, три поля ввода в форме отключены, но мне нужно, чтобы они заполнялись, когда я выбираю значение в первом поле выбора за пределами формы. Можете ли вы предложить мне другой подход?


person palnic    schedule 16.07.2021    source источник


Ответы (1)


Вы можете подключить ввод или кнопку к форме вне формы.

как этот код:


<form id="myForm">


<button> click me </button>
</form>


<input type="text" form="myForm"/>

ссылка: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefform

person Alireza Amini    schedule 16.07.2021