简体   繁体   English

使用 Formik 在语义 UI 中选择

[英]Use select in Semantic UI with Formik

I'm usign Formik to validate some data fields with Semantic UI in React.我使用Formik在 React 中使用语义 UI验证一些数据字段。 It works fine with input fields but doesn't work with selectors.它适用于输入字段,但不适用于选择器。

How it works with input fields:它如何处理输入字段:

    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>;

However, when the as={Input} is replaced by as={Select} , it doesn't work.但是,当as={Input}替换为as={Select} ,它不起作用。 The dropdown gets opened when I click on the selector, it shows the options ( company1 and company2 ), I click on one of them but it does not work -> the value shown is still the placeholder value.当我点击选择器时,下拉菜单被打开,它显示了选项( company1company2 ),我点击其中一个但它不起作用 - >显示的值仍然是占位符值。

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>;

The reason is because Formik passes an onChange function into the component.原因是因为 Formik 传递了一个onChange函数到组件中。 However, the Select (which is just syntactic sugar for dropdown https://react.semantic-ui.com/addons/select/ ) onChange prop uses a function of shape handleChange = (e: React.SyntheticEvent<HTMLElement>, data: SelectProps) => this.setState({value: data.value}) ( https://react.semantic-ui.com/modules/dropdown/#usage-controlled ) which is different than the conventional handleChange = (event: React.SyntheticEvent<HTMLElement>) => this.setState({value: event.target.value}) which formik uses.但是, Select (这只是下拉https://react.semantic-ui.com/addons/select/ 的语法糖) onChange道具使用形状handleChange = (e: React.SyntheticEvent<HTMLElement>, data: SelectProps) => this.setState({value: data.value}) ( https://react.semantic-ui.com/modules/dropdown/#usage-controlled ) 不同于传统的handleChange = (event: React.SyntheticEvent<HTMLElement>) => this.setState({value: event.target.value})

So an easy solution would be to use the Formik function setFieldValue .所以一个简单的解决方案是使用 Formik 函数setFieldValue

In your code, the implementation would be something like this:在您的代码中,实现将是这样的:

 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>;

Here's a somewhat working version using your code.这是一个使用您的代码的工作版本。 The fields update (verified with a console.log), but the submit button isn't working 🤷‍♂️: https://codesandbox.io/s/formik-and-semanticui-select-gb7o7字段更新(使用 console.log 验证),但提交按钮不起作用🤷‍♂️: https ://codesandbox.io/s/formik-and-semanticui-select-gb7o7

This is a somewhat incomplete solution and does not handle the onBlur and other injected formik functions.这是一个有点不完整的解决方案,不处理 onBlur 和其他注入的 formik 函数。 It also defeats the purpose of Formik somewhat.这也有点违背了 Formik 的目的。 A better solution would be to create a HOC that wraps semantic ui components to use Fromik correctly: https://github.com/formium/formik/issues/148 .更好的解决方案是创建一个 HOC 来包装语义 ui 组件以正确使用 Fromik: https : //github.com/formium/formik/issues/148

And lastly, you can skip the Semantic UI Select and use the Semantic UI HTML controlled select : https://react.semantic-ui.com/collections/form/#shorthand-field-control-html .最后,您可以跳过语义 UI 选择并使用语义 UI HTML 控制selecthttps : //react.semantic-ui.com/collections/form/#shorthand-field-control-html Notice the select vs Select .注意selectSelect This will work natively with Formik without the need to pass in onChange and value .这将与 Formik 一起使用,无需传入onChangevalue

I recently created a binding library for Semantic UI React & Formik .我最近为Semantic UI React & Formik创建了一个绑定库。

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

You just need to import Select from the library and fill in name & options props.您只需要从库中导入Select并填写nameoptions道具。

// 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>;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM