在 React 中根据状态设置表单的值

Set the value of a form based on state in React

使用 Formik 验证某些字段,如果状态值为真,我希望将一个字段的值复制到另一个字段的值。

例如,要将 mainAddress 的值复制到 address

有一个状态变量 setAddress,它设置为 false,但可以在单击复选框时将其更改为 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 && 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)

None 他们的工作。是否可以从 values.mainAddress 获取值并将其复制到 values.address?或者输入?

您可以相应地重写地址的字段组件。

<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 值填充它。

这是工作代码和框代码 - https://codesandbox.io/s/fervent-tereshkova-sro93?file=/index.js

Formik 还提供了值对象,您可以使用它来更新与 mainAddress 相同的地址值。只需为两个输入字段提供名称属性,然后像这样分配 - props.values.address = {...props.values.mainAddress}