【问题标题】:Use select in Semantic UI with Formik使用 Formik 在语义 UI 中选择
【发布时间】:2020-09-05 19:25:29
【问题描述】:

我使用Formik 在 React 中使用Semantic UI 验证一些数据字段。它适用于输入字段,但不适用于选择器。

如何处理输入字段:

    import { Formik, Form, Field } from 'formik';
    import { Input, Button, Select, Label, Grid } from 'semantic-ui-react';
    import * as Yup from 'yup';

    ...

  const initialValues = {
     name: ''
  };
  const requiredErrorMessage = 'This field is required';
  const validationSchema = Yup.object({ name: Yup.string().required(requiredErrorMessage) });
   
  <Formik
  htmlFor="amazing"
  initialValues={initialValues}
  validationSchema={validationSchema}
  onSubmit={values => this.handleSubmit(values)}>
  {({ errors, touched }) => (
    <Form id="amazing">
      <div>
        <CreationContentContainer>
          <Grid>
            <Grid.Column>
              <Label>Company name</Label>
              <Field name="name" as={Input} placeholder="name" /> // here is the input 
              <div>{touched.name && errors.name ? errors.name : null}</div>
            </Grid.Column>
          </Grid>
        </CreationContentContainer>
        <Button type="submit" form="amazing">
          Create company
        </Button>
      </div>
    </Form>
  )}
</Formik>;

但是,当as={Input} 被as={Select} 替换时,它就不起作用了。当我单击选择器时,下拉菜单打开,它显示选项(company1 和 company2),我单击其中一个但它不起作用 -> 显示的值仍然是占位符值。

import { Formik, Form, Field } from 'formik';
import { Input, Button, Select, Label, Grid } from 'semantic-ui-react';
import * as Yup from 'yup';

const companyOptions = [ // the select's options
  { text: 'company1', value: 'company1' },
  { text: 'company2', value: 'company2' },
];

<Formik
  htmlFor="amazing"
  initialValues={initialValues}
  validationSchema={validationSchema}
  onSubmit={values => this.handleSubmit(values)}>
  {({ errors, touched }) => (
    <Form id="amazing">
      <div>
        <CreationContentContainer>
          <Grid>
            <Grid.Column>
              <Label>Company name</Label>
              <Field
                name="name"
                as={Select} // here is changed to Select
                options={companyOptions} // the options
                placeholder="name"
              />
              <div>{touched.name && errors.name ? errors.name : null}</div>
            </Grid.Column>
          </Grid>
        </CreationContentContainer>
        <Button type="submit" form="amazing">
          Create company
        </Button>
      </div>
    </Form>
  )}
</Formik>;

【问题讨论】:

    标签: javascript reactjs semantic-ui formik semantic-ui-react


    【解决方案1】:

    原因是因为 Formik 将 onChange 函数传递给组件。但是,Select(这只是下拉 https://react.semantic-ui.com/addons/select/ 的语法糖)onChange 属性使用形状为 handleChange = (e: React.SyntheticEvent&lt;HTMLElement&gt;, data: SelectProps) =&gt; this.setState({value: data.value}) (https://react.semantic-ui.com/modules/dropdown/#usage-controlled) 的函数,这与 formik 使用的常规 handleChange = (event: React.SyntheticEvent&lt;HTMLElement&gt;) =&gt; this.setState({value: event.target.value}) 不同。

    所以一个简单的解决方案是使用 Formik 函数setFieldValue。

    在您的代码中,实现将是这样的:

    const companyOptions = [ // the select's options
      { text: 'company1', value: 'company1' },
      { text: 'company2', value: 'company2' },
    ];
    
    <Formik
      htmlFor="amazing"
      initialValues={initialValues}
      validationSchema={validationSchema}
      onSubmit={values => this.handleSubmit(values)}>
      {({ errors, touched, setFieldValue, values }) => {
        const handleChange = (e, { name, value }) => setFieldValue(name, value));
        return (
          <Form id="amazing">
            <div>
              <CreationContentContainer>
                <Grid>
                  <Grid.Column>
                    <Label>Company name</Label>
                    <Field
                      name="name"
                      as={Select} // here is changed to Select
                      options={companyOptions} // the options
                      placeholder="name"
                      onChange={handleChange}
                      value={values.name}
                    />
                    <div>{touched.name && errors.name ? errors.name : null}</div>
                  </Grid.Column>
                </Grid>
              </CreationContentContainer>
              <Button type="submit" form="amazing">
                Create company
              </Button>
            </div>
          </Form>
      )}
    }
    </Formik>;

    这是一个使用您的代码的工作版本。字段更新(通过 console.log 验证),但提交按钮不起作用?‍♂️:https://codesandbox.io/s/formik-and-semanticui-select-gb7o7

    这是一个有点不完整的解决方案,不处理 onBlur 和其他注入的 formik 函数。它也有点违背了 Formik 的目的。更好的解决方案是创建一个包装语义 ui 组件以正确使用 Fromik 的 HOC:https://github.com/formium/formik/issues/148。

    最后,您可以跳过语义 UI 选择并使用语义 UI HTML 控制 select: https://react.semantic-ui.com/collections/form/#shorthand-field-control-html。注意select 与Select。这将与 Formik 一起工作,无需传入 onChange 和 value。

    【讨论】:

      【解决方案2】:

      我最近为Semantic UI React 和Formik 创建了一个绑定库。

      链接:https://github.com/JT501/formik-semantic-ui-react

      你只需要从库中导入Select并填写name & options props即可。

      // Import components
      import { Select, SubmitButton } from "formik-semantic-ui-react";
      
      const companyOptions = [ // the select's options
        { text: 'company1', value: 'company1' },
        { text: 'company2', value: 'company2' },
      ];
      
      <Formik
        htmlFor="amazing"
        initialValues={initialValues}
        validationSchema={validationSchema}
        onSubmit={values => this.handleSubmit(values)}>
        {({ errors, touched }) => (
          <Form id="amazing">
            <div>
              <CreationContentContainer>
                <Grid>
                  <Grid.Column>
                    <Label>Company name</Label>
      
                    <Select
                       name="name"
                       selectOnBlur={false}
                       clearable
                       placeholder="name"
                       options={companyOptions}
                    />
      
                  </Grid.Column>
                </Grid>
              </CreationContentContainer>
              <SubmitButton>
                Create company
              </SubmitButton>
            </div>
          </Form>
        )}
      </Formik>;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-10-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-01
        • 2022-07-28
        • 2018-04-27
        相关资源
        最近更新 更多