Установка значения формы на основе состояния в React

#javascript #reactjs #setstate #formik #yup

#javascript #reactjs #setstate #formik #ага

Вопрос:

Используя Formik для проверки некоторых полей, если значение состояния равно true, я хочу, чтобы значение одного поля копировалось в значение другого.

Например, значение mainAddress , в которое нужно скопировать address .

Существует переменная состояния, setAddress для которой установлено значение false, но ее можно изменить на true при нажатии флажка.

Когда для этой переменной установлено значение true, я хочу, чтобы значение mainAddress копировалось в address

Это код, который отлично работает без копирования этого значения:

 import React from 'react';
import { Formik, Form, Field } from 'formik';
import { Input, Button, Label, Grid } from 'semantic-ui-react';
import * as Yup from 'yup';
import { Creators } from '../../../actions';
import './CreateCompanyForm.scss';

class CreateCompanyForm extends React.PureComponent {
  constructor(props) {
    super(props);

    this.state = { // state variables 
      address: '',
      mainAddress: '',
      setAddress: false,
    };
  }

  handleSubmit = values => {
    // create company
  };

  toggleAddress = () => { // it toggles the value of setAddress
    this.setState(prevState => ({
      setAddress: !prevState.setAddress,
    }));
  };

  render() {
    const initialValues = { // the address and mainAddress are set to '' at the start
      address: '',
      mainAddress: '',
    };
    const validationSchema = Yup.object({
      address: Yup.string().required('error'),
      mainAddress: Yup.string().required('error'),
    });
    return (
      <>
        <Button type="submit" form="amazing"> // button for submit
          Create company
        </Button>

        <Formik
          htmlFor="amazing"
          initialValues={initialValues}
          validationSchema={validationSchema}
          onSubmit={values => this.handleSubmit(values)}>
          {({ values, errors, touched, setValues, setFieldValue }) => (
            <Form id="amazing">
              <Grid>
                <Grid.Column> // mainAddress value
                  <Label>Main Address</Label>
                  <Field name="mainAddress" as={Input} />
                </Grid.Column>

                <Grid.Column> // address value
                  <Label>Address</Label>
                  <Field name="address" as={Input} />
                  <div>
                    {this.state.setAddress // here is how I've tried to set that value
                      ? values.address.setFieldValue(values.mainAddress)
                      : console.log('nope')}
                    {touched.address amp;amp; errors.address ? errors.address : null}
                  </div>
                </Grid.Column>
              </Grid>
              <Checkbox
                label="Use same address"
                onClick={() => this.toggleAddress()}
              />
            </Form>
          )}
        </Formik>
      </>
    );
  }
}
  

Итак, я пробовал другие способы ее решения, но безуспешно. Теперь в коде это:

  {this.state.setAddress
     ? values.address.setFieldValue(values.mainAddress)
     : console.log('nope')}
  

Другой был: (this.state.setAddress ? values.address = values.mainAddress)

Ни один из них не работает. Возможно ли получить значение из values.mainAddress и скопировать его в values.address ? Или на его ввод?

Ответ №1:

Вы можете соответствующим образом переписать компонент поля для адреса.

 <Field name="address">
 {({
    field, // { name, value, onChange, onBlur }
 }) => {
   values.address = values.mainAddress;
   return (
     <div>
        <input
           {...field}
           type="text"
           placeholder="Address"
         />
      </div>
    );
  }}
</Field>
  

Здесь мы устанавливаем значение поля адреса в values.mainAddress если установлен флажок setAdress, иначе мы позволим formik value заполнить его.

Вот рабочий код codesandbox — https://codesandbox.io/s/fervent-tereshkova-sro93?file=/index.js

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

1. Он работает для получения значения из mainAddress и копирования в address . Однако я не могу отправить форму, потому что в ней указано, что она недействительна. Это происходит потому, что оно не обновляется для values объекта. Этот объект выглядит следующим образом: { address: "", mainAddress: "mytext"} . Есть ли способ обновить и это? Я пробовал, например: this.state.setAddress ? (values.mainAddress, values.address = values.mainAddress) : field.value } но это не работает, ошибка: Arrow function should not return assignment и Assignment to property of function parameter 'values'

2. Я обновил ответ. Пожалуйста, проверьте. Теперь это должно сработать. Я также обновил код codesandbox.

Ответ №2:

Formik также предоставляет объект values, который вы можете использовать для обновления значения адреса, аналогичного mainAddress. Просто укажите атрибут name для обоих полей ввода, а затем назначьте так — props.values.address = {…props.values.mainAddress}

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

1. не могли бы вы расширить свой ответ, пожалуйста?

2. Поскольку вы деструктурировали значения из этого в своем коде {({ values, errors, touched, setValues, setFieldValue }) , вы можете сделать это при срабатывании onClick внутри вашего флажка: onClick ={() => values.address = values.mainAddress}