【问题标题】:Set the value of a form based on state in React根据 React 中的状态设置表单的值
【发布时间】:2020-09-23 14:50:27
【问题描述】:

使用 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 && 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?还是对其输入?

【问题讨论】:

    标签: javascript reactjs setstate formik yup


    【解决方案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 值填充它。

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

    【讨论】:

    • 它可以从mainAddress获取值并复制到address。但是,我无法提交表单,因为它说它无效。发生这种情况是因为它没有在 values 对象上更新。该对象如下所示:{ address: "", mainAddress: "mytext"}。有没有办法更新那个?我试过像:this.state.setAddress ? (values.mainAddress, values.address = values.mainAddress) : field.value } 但它不起作用,错误:Arrow function should not return assignmentAssignment to property of function parameter 'values'
    • 我更新了答案。请检查。现在应该可以了。我也更新了代码框代码。
    【解决方案2】:

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

    【讨论】:

    • 你能扩展你的答案吗?
    • 当您在代码 {({ values, errors, touched, setValues, setFieldValue }) 中从这里解构值时,您可以在触发复选框内的 onClick 时执行此操作:onClick ={() =&gt; values.address = values.mainAddress}
    猜你喜欢
    • 2017-07-18
    • 2019-10-20
    • 1970-01-01
    • 1970-01-01
    • 2017-06-11
    • 1970-01-01
    • 2013-12-16
    • 2021-03-28
    • 1970-01-01
    相关资源
    最近更新 更多