使用 Semantic-UI-React 进行表单验证
Form Validation with Semantic-UI-React
我正在使用官方 Semantic UI React 组件来创建 Web 应用程序。我的注册页面上有一个表单,其中包含一个电子邮件字段、一个密码字段和一个确认密码字段。
import {Component} from 'react';
import {Button, Form, Message} from 'semantic-ui-react';
import {signUp} from '../../actions/auth';
class SignUp extends Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e, {formData}) {
e.preventDefault();
//
// Potentially need to manually validate fields here?
//
// Send a POST request to the server with the formData
this.props.dispatch(signUp(formData)).then(({isAuthenticated}) => {
if (isAuthenticated) {
// Redirect to the home page if the user is authenticated
this.props.router.push('/');
}
}
}
render() {
const {err} = this.props;
return (
<Form onSubmit={this.handleSubmit} error={Boolean(err)}>
<Form.Input label="Email" name="email" type="text"/>
<Form.Input label="Password" name="password" type="password"/>
<Form.Input label="Confirm Password" name="confirmPassword" type="password"/>
{err &&
<Message header="Error" content={err.message} error/>
}
<Button size="huge" type="submit" primary>Sign Up</Button>
</Form>
);
}
}
现在,我已经习惯了常规的语义 UI 库,它有一个 Form Validation addon。通常,我会在单独的 JavaScript 文件
中定义这样的规则
$('.ui.form').form({
fields: {
email: {
identifier: 'email',
rules: [{
type: 'empty',
prompt: 'Please enter your email address'
}, {
type: 'regExp',
value: "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?",
prompt: 'Please enter a valid email address'
}]
},
password: {
identifier: 'password',
rules: [{
type: 'empty',
prompt: 'Please enter your password'
}, {
type: 'minLength[8]',
prompt: 'Your password must be at least {ruleValue} characters'
}]
},
confirmPassword: {
identifier: 'confirmPassword',
rules: [{
type: 'match[password]',
prompt: 'The password you provided does not match'
}]
}
}
});
是否有类似的方法使用语义 UI React 组件来验证表单?我搜索了文档但没有成功,而且似乎没有使用此语义 UI React 库进行验证的示例。
我是否需要在 handleSubmit
函数中手动验证每个字段?解决此问题的最佳方法是什么?感谢您的帮助!
Do I instead need to validate each field by hand in the handleSubmit
function?
悲伤,但真实。苏尔 doesn't have form validation at now. However, you can use HOC to work with forms like redux-form.
在大多数情况下,您必须手动验证表单。但是,RSUI 包含一些工具可以让事情变得更简单,特别是 <Form>
和 <Form.Input>
上的错误属性
这是我最近整理的一个表格示例。它可以使用一些重构,但它基本上是通过将每个输入与一个 onChange()
函数绑定到状态,并将回调传递给控制加载屏幕可见性和 "Success. Thank you for submitting" 的提交函数来工作的表格的一部分。
export default class MeetingFormModal extends Component {
constructor(props) {
super(props)
this.state = {
firstName: '',
lastName: '',
email: '',
location: '',
firstNameError: false,
lastNameError: false,
emailError: false,
locationError: false,
formError: false,
errorMessage: 'Please complete all required fields.',
complete: false,
modalOpen: false
}
this.submitMeetingForm = this.submitMeetingForm.bind(this);
this.successCallback = this.successCallback.bind(this);
}
successCallback() {
this.setState({
complete: true
})
setTimeout( () => {this.setState({modalOpen: false})}, 5000);
this.props.hideLoading();
}
handleClose = () => this.setState({ modalOpen: false })
handleOpen = () => this.setState({ modalOpen: true })
submitMeetingForm() {
let error = false;
if (this.state.studentFirstName === '') {
this.setState({firstNameError: true})
error = true
} else {
this.setState({firstNameError: false})
error = false
}
if (this.state.studentLastName === '') {
this.setState({lastNameError: true})
error = true
} else {
this.setState({lastNameError: false})
error = false
}
if (this.state.email === '') {
this.setState({emailError: true})
error = true
} else {
this.setState({emailError: false})
error = false
}
if (this.state.location === '') {
this.setState({locationError: true})
error = true
} else {
this.setState({locationError: false})
error = false
}
if (error) {
this.setState({formError: true})
return
} else {
this.setState({formError: false})
}
let meeting = {
first_name: this.state.firstName,
last_name: this.state.lastName,
email: this.state.email,
location: this.state.location,
this.props.createMeeting(meeting, this.successCallback)
this.props.showLoading();
}
capitalize(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
render() {
return(
<Modal
trigger={<Button onClick={this.handleOpen} basic color='blue'>Schedule Now</Button>}
open={this.state.modalOpen}
onClose={this.handleClose}
closeIcon={true}
>
<Modal.Header>Schedule Your Interview</Modal.Header>
<Modal.Content>
{!this.state.complete ?
<Modal.Description>
<Form error={this.state.formError}>
<Form.Group widths='equal'>
<Form.Field>
<Form.Input required={true} onChange={(e) => this.setState({firstName: e.target.value})} label='First Name' placeholder="First Name..." error={this.state.firstNameError}/>
</Form.Field>
<Form.Field>
<Form.Input required={true} onChange={(e) => this.setState({lastName: e.target.value})} label='Last Name' placeholder="Last Name..." error={this.state.lastNameError}/>
</Form.Field>
</Form.Group>
<Form.Field >
<Form.Input required={true} onChange={(e) => this.setState({email: e.target.value})} label='Email' placeholder="Email..." error={this.state.emailError}/>
</Form.Field>
<Form.Field>
<Form.Input required={true} onChange={(e) => this.setState({location: e.target.value})} label='Location' placeholder='City, State/Province, Country...' error={this.state.locationError}/>
</Form.Field>
</Form>
</Modal.Description>
:
<div className='modal-complete'>
<Image src='/images/check.png' />
<p>Thanks for scheduling a meeting, {this.capitalize(this.state.name)}. We've received your information and we'll be in touch shortly.</p>
</div>
}
</Modal.Content>
{!this.state.complete ?
<Modal.Actions>
<Button color='red' onClick={this.handleClose}>Close</Button>
<Button positive icon='checkmark' labelPosition='right' content="Submit" onClick={this.submitMeetingForm} />
</Modal.Actions>
: null }
</Modal>
)
}
}
希望对您有所帮助!
您可以使用插件进行验证。
插件名称:formsy-semantic-ui-react
下面的代码实质上是为每个组件名称和相关值设置状态。 (即,状态可能看起来像 {marketSide:buy, price:50, quantity:9} 我也将表单错误信息填充到状态中,利用 yup 的默认行为不验证未提及的字段通过验证架构。
要点:
1) 对 schema.validate(someObjectToValidate, yupProperties) 的调用(其中 someObjectToValidate 只是 this.state),应该传入 {abortEarly:false} 作为属性对象,以覆盖 yups 默认值一旦遇到单个错误就停止验证的行为,因为我们的表单的消息组件会向用户显示所有错误。
2)如果 yup 验证失败,yup 会抛出一个异常,所以我们捕获异常并挑选出我们感兴趣的错误信息,并用这个错误更新我们的状态。
3)我们必须使用 this.setState(...) 的 'callback form',因为 setState 是异步的,因此状态对象的验证仅在状态更新后发生。
4) 如果 yup 验证成功,我们清除我们的错误和 errorPath 数组。
5) 这是一个快速的解决方案,我在每次渲染时多次检查 errorPaths 数组。最好将 errorPath 和错误信息存储在由组件名称键入的 json 对象中,而不是存储在两个数组中,以改进当前解决方案的(2 个数组 * N 个字段 * N 个潜在错误 = O( 2n^2) 表现。
6)忽略长样式的“<Form.Field control={Radio}>
”符号,您可以使用较短的 <Input>, <Button>, <Radio>,
等样式。此语法与验证无关。也忽略 div。
import React, { Component } from 'react'
import { Button, Checkbox, Form, Input, Radio, Select, Message, Label } from 'semantic-ui-react'
import * as yup from 'yup';
const options = [
{ text: 'buy', value: 'buy' },
{ text: 'sell', value: 'sell' },
]
class OrderEntryV3 extends Component {
state = {
errorPaths:[],
errors:[]
}
constructor(props){
super(props);
}
schema = yup.object().shape({
quantity: yup.number().required().positive().integer(),
price: yup.number().required().positive(),
marketSide: yup.string().required(),
orderType : yup.string().required()
});
handleChange = (e, component) => {
this.setState({[component.name]:component.value}, ()=>this.schema.validate(this.state, {abortEarly:false})
.then(valid=>this.setState({errorPaths:[], errors:[]})) //called if the entire form is valid
.catch(err=>this.setState({errors:err.errors, errorPaths: err.inner.map(i=>i.path) }))) //called if any field is invalid
};
render() {
return (
<div id="oeform-content">
<div id="oeform-left">
<Form>
<Form.Field error={this.state.errorPaths.includes('marketSide')} name="marketSide" control={Select} label='Market side' options={options} placeholder='market side' onChange={this.handleChange}/>
<Form.Field error={this.state.errorPaths.includes('quantity')} type='number' name="quantity" control={Input} label='Quantity' placeholder='quantity' onChange={this.handleChange}/>
<Form.Group>
<label><b>Order type</b></label>
<Form.Field error={this.state.errorPaths.includes('orderType')} >
<Radio
label='market'
name='orderType'
value='market'
checked={this.state.orderType === 'market'}
onChange={this.handleChange}
/>
</Form.Field>
<Form.Field error={this.state.errorPaths.includes('orderType')}>
<Radio
label='limit'
name='orderType'
value='limit'
checked={this.state.orderType === 'limit'}
onChange={this.handleChange}
/>
</Form.Field>
</Form.Group>
<Form.Field error={this.state.errorPaths.includes('price')} name='price' control={Input} type='number' label='Price' placeholder='price' onChange={this.handleChange}/>
<Form.Field control={Button} disabled={!!this.state.errors.length}>Submit</Form.Field>
<Message visible={!!this.state.errors.length} warning
header='Please correct the following issues: '
list={this.state.errors}/>
</Form>
</div>
<div id="oeform-right">
<p>{JSON.stringify(this.state)}</p>
</div>
</div>
)
}
}
export default OrderEntryV3
我们甚至有更好的选择,尽管语义-ui-react 没有提供 -> Formik + yup
Formik:帮助管理表单状态
是的:有助于验证该状态
我有下面的组件,它基本上是一个使用 semantic-ui-react 创建的编辑表单。
import React, { Component } from "react";
import { Button, Form, Modal, Message, Divider } from "semantic-ui-react";
import { Formik } from "formik";
import * as yup from "yup";
class EditAboutGrid extends Component {
render() {
const {
userBasic,
editBasicModal,
closeModal
} = this.props;
return (
<Formik
initialValues={{
firstName: userBasic.firstName,
lastName: userBasic.lastName,
bio: userBasic.bio,
}}
validationSchema={yup.object().shape({
firstName: yup
.string()
.required("Name cannot be empty"),
lastName: yup
.string()
.required("Name cannot be empty"),
bio: yup
.string()
.max(1000, "Maximum characters exceed 1000")
.nullable()
})}
onSubmit={(values, actions) => {
//do your stuff here like api calls
}}
render={({
values,
errors,
handleChange,
handleSubmit,
isSubmitting,
dirty,
setFieldValue
}) => (
<Modal open={editBasicModal} size="small">
<Modal.Header>Your basic details</Modal.Header>
<Modal.Content scrolling>
{errors.firstName && <Message error content={errors.firstName} />}
{errors.lastName && <Message error content={errors.lastName} />}
{errors.bio && <Message error content={errors.bio} />}
<Form loading={isSubmitting}>
<Form.Group inline widths="equal">
<Form.Input
required
label="First Name"
fluid
type="text"
name="firstName"
value={values.firstName}
onChange={handleChange}
error={errors.firstName !== undefined}
/>
<Form.Input
required
label="Last Name"
fluid
type="text"
name="lastName"
value={values.lastName}
onChange={handleChange}
error={errors.lastName !== undefined}
/>
</Form.Group>
<Form.TextArea
label="Bio"
type="text"
name="bio"
value={values.bio}
onChange={handleChange}
rows={3}
error={errors.bio !== undefined}
/>
</Form>
</Modal.Content>
<Modal.Actions open={true}>
<Button
onClick={() => (dirty ? closeModal(true) : closeModal(false))}>
Cancel
</Button>
<Button
primary
type="submit"
onClick={handleSubmit}
loading={isSubmitting}
disabled={isSubmitting || !isEmpty(errors) || !dirty}>
Update
</Button>
</Modal.Actions>
</Modal>
)}
/>
);
}
}
并且调用此表单使用:
<EditAboutGrid
editBasicModal={this.state.editBasicModal}
userBasic={this.state.user.basic}
closeModal={this.closeModal}
/>
initialValues
是事情开始的地方。在这里,您将 initial/default 值传递给表单的输入。 values
(in form) 将从该默认值中选取数据值。
validationSchema
是使用 yup
进行所有验证的地方
onSubmit
将在表单提交时调用。
使用 Formik + yup 处理表单非常简单。我很喜欢它。
我知道这已经有几年的历史了,并不是所问问题的完整解决方案,但今天看到的任何人都可能会发现这很有用,因为我一直在寻找相同的东西并且 运行 进入这个线程。虽然 semantic-ui-react 没有我能找到的表单验证,但它有一个很好的方式来显示表单验证错误。您仍然必须自己进行验证。请参阅 semantic-ui-react forms documentation page for an example of how it shows validation errors. It also has a feature to show success message. I have created an example 了解如何根据状态控制错误消息。在此示例中,您可以使用“显示性别错误”复选框来切换性别输入的错误消息。
对于语义验证形式-ui你可以简单地实现而不需要任何插件
<Form.Field
id='form-input-control-project-name'
control={Input}
label='Project Name'
placeholder='Project name'
onChange={this.handleChange}
error={this.state.projectName}
/>
this.state.projectName 在这个变量中你必须存储false/error消息
如果值为false不显示错误否则显示错误
我知道这个问题已经有好几年了,但这是我在使用(相对)较新的 React 功能组件和 Hooks 时遇到的困难 API。就我而言,我只是想验证用户输入的电子邮件地址是否有效。我最终通过下面的代码得到了我正在寻找的行为。
import React, {useState} from 'react';
import { Form } from 'semantic-ui-react'
import EmailValidator from 'email-validator';
function MyFormComponentExample() {
const [emailInput, setEmail] = useState("");
const [validEmail, validateEmail] = useState(true);
return (
<Form>
<Form.Input
icon='envelope'
iconPosition='left'
label='Email'
placeholder='Email Address'
required
value={emailInput}
onChange={e => {
setEmail(e.target.value);
validateEmail(EmailValidator.validate(e.target.value));
}}
error={validEmail ? false : {
content: 'Please enter a valid email address.',
pointing: 'below'
}}
/>
</Form>
);
}
export default MyFormComponentExample;
弄清楚后,我认为这个结构足够简单,但如果有人对执行此操作的更好模式或方法有任何反馈,我很乐意听到!
您可以使用 Formik 进行验证。
并且我创建了一个库来绑定 Formik 和 Semantic UI React。
https://github.com/JT501/formik-semantic-ui-react
一个简单的例子:
Codesandbox
我正在使用官方 Semantic UI React 组件来创建 Web 应用程序。我的注册页面上有一个表单,其中包含一个电子邮件字段、一个密码字段和一个确认密码字段。
import {Component} from 'react';
import {Button, Form, Message} from 'semantic-ui-react';
import {signUp} from '../../actions/auth';
class SignUp extends Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e, {formData}) {
e.preventDefault();
//
// Potentially need to manually validate fields here?
//
// Send a POST request to the server with the formData
this.props.dispatch(signUp(formData)).then(({isAuthenticated}) => {
if (isAuthenticated) {
// Redirect to the home page if the user is authenticated
this.props.router.push('/');
}
}
}
render() {
const {err} = this.props;
return (
<Form onSubmit={this.handleSubmit} error={Boolean(err)}>
<Form.Input label="Email" name="email" type="text"/>
<Form.Input label="Password" name="password" type="password"/>
<Form.Input label="Confirm Password" name="confirmPassword" type="password"/>
{err &&
<Message header="Error" content={err.message} error/>
}
<Button size="huge" type="submit" primary>Sign Up</Button>
</Form>
);
}
}
现在,我已经习惯了常规的语义 UI 库,它有一个 Form Validation addon。通常,我会在单独的 JavaScript 文件
中定义这样的规则$('.ui.form').form({
fields: {
email: {
identifier: 'email',
rules: [{
type: 'empty',
prompt: 'Please enter your email address'
}, {
type: 'regExp',
value: "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?",
prompt: 'Please enter a valid email address'
}]
},
password: {
identifier: 'password',
rules: [{
type: 'empty',
prompt: 'Please enter your password'
}, {
type: 'minLength[8]',
prompt: 'Your password must be at least {ruleValue} characters'
}]
},
confirmPassword: {
identifier: 'confirmPassword',
rules: [{
type: 'match[password]',
prompt: 'The password you provided does not match'
}]
}
}
});
是否有类似的方法使用语义 UI React 组件来验证表单?我搜索了文档但没有成功,而且似乎没有使用此语义 UI React 库进行验证的示例。
我是否需要在 handleSubmit
函数中手动验证每个字段?解决此问题的最佳方法是什么?感谢您的帮助!
Do I instead need to validate each field by hand in the handleSubmit function?
悲伤,但真实。苏尔 doesn't have form validation at now. However, you can use HOC to work with forms like redux-form.
在大多数情况下,您必须手动验证表单。但是,RSUI 包含一些工具可以让事情变得更简单,特别是 <Form>
和 <Form.Input>
这是我最近整理的一个表格示例。它可以使用一些重构,但它基本上是通过将每个输入与一个 onChange()
函数绑定到状态,并将回调传递给控制加载屏幕可见性和 "Success. Thank you for submitting" 的提交函数来工作的表格的一部分。
export default class MeetingFormModal extends Component {
constructor(props) {
super(props)
this.state = {
firstName: '',
lastName: '',
email: '',
location: '',
firstNameError: false,
lastNameError: false,
emailError: false,
locationError: false,
formError: false,
errorMessage: 'Please complete all required fields.',
complete: false,
modalOpen: false
}
this.submitMeetingForm = this.submitMeetingForm.bind(this);
this.successCallback = this.successCallback.bind(this);
}
successCallback() {
this.setState({
complete: true
})
setTimeout( () => {this.setState({modalOpen: false})}, 5000);
this.props.hideLoading();
}
handleClose = () => this.setState({ modalOpen: false })
handleOpen = () => this.setState({ modalOpen: true })
submitMeetingForm() {
let error = false;
if (this.state.studentFirstName === '') {
this.setState({firstNameError: true})
error = true
} else {
this.setState({firstNameError: false})
error = false
}
if (this.state.studentLastName === '') {
this.setState({lastNameError: true})
error = true
} else {
this.setState({lastNameError: false})
error = false
}
if (this.state.email === '') {
this.setState({emailError: true})
error = true
} else {
this.setState({emailError: false})
error = false
}
if (this.state.location === '') {
this.setState({locationError: true})
error = true
} else {
this.setState({locationError: false})
error = false
}
if (error) {
this.setState({formError: true})
return
} else {
this.setState({formError: false})
}
let meeting = {
first_name: this.state.firstName,
last_name: this.state.lastName,
email: this.state.email,
location: this.state.location,
this.props.createMeeting(meeting, this.successCallback)
this.props.showLoading();
}
capitalize(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
render() {
return(
<Modal
trigger={<Button onClick={this.handleOpen} basic color='blue'>Schedule Now</Button>}
open={this.state.modalOpen}
onClose={this.handleClose}
closeIcon={true}
>
<Modal.Header>Schedule Your Interview</Modal.Header>
<Modal.Content>
{!this.state.complete ?
<Modal.Description>
<Form error={this.state.formError}>
<Form.Group widths='equal'>
<Form.Field>
<Form.Input required={true} onChange={(e) => this.setState({firstName: e.target.value})} label='First Name' placeholder="First Name..." error={this.state.firstNameError}/>
</Form.Field>
<Form.Field>
<Form.Input required={true} onChange={(e) => this.setState({lastName: e.target.value})} label='Last Name' placeholder="Last Name..." error={this.state.lastNameError}/>
</Form.Field>
</Form.Group>
<Form.Field >
<Form.Input required={true} onChange={(e) => this.setState({email: e.target.value})} label='Email' placeholder="Email..." error={this.state.emailError}/>
</Form.Field>
<Form.Field>
<Form.Input required={true} onChange={(e) => this.setState({location: e.target.value})} label='Location' placeholder='City, State/Province, Country...' error={this.state.locationError}/>
</Form.Field>
</Form>
</Modal.Description>
:
<div className='modal-complete'>
<Image src='/images/check.png' />
<p>Thanks for scheduling a meeting, {this.capitalize(this.state.name)}. We've received your information and we'll be in touch shortly.</p>
</div>
}
</Modal.Content>
{!this.state.complete ?
<Modal.Actions>
<Button color='red' onClick={this.handleClose}>Close</Button>
<Button positive icon='checkmark' labelPosition='right' content="Submit" onClick={this.submitMeetingForm} />
</Modal.Actions>
: null }
</Modal>
)
}
}
希望对您有所帮助!
您可以使用插件进行验证。 插件名称:formsy-semantic-ui-react
下面的代码实质上是为每个组件名称和相关值设置状态。 (即,状态可能看起来像 {marketSide:buy, price:50, quantity:9} 我也将表单错误信息填充到状态中,利用 yup 的默认行为不验证未提及的字段通过验证架构。
要点:
1) 对 schema.validate(someObjectToValidate, yupProperties) 的调用(其中 someObjectToValidate 只是 this.state),应该传入 {abortEarly:false} 作为属性对象,以覆盖 yups 默认值一旦遇到单个错误就停止验证的行为,因为我们的表单的消息组件会向用户显示所有错误。
2)如果 yup 验证失败,yup 会抛出一个异常,所以我们捕获异常并挑选出我们感兴趣的错误信息,并用这个错误更新我们的状态。
3)我们必须使用 this.setState(...) 的 'callback form',因为 setState 是异步的,因此状态对象的验证仅在状态更新后发生。
4) 如果 yup 验证成功,我们清除我们的错误和 errorPath 数组。
5) 这是一个快速的解决方案,我在每次渲染时多次检查 errorPaths 数组。最好将 errorPath 和错误信息存储在由组件名称键入的 json 对象中,而不是存储在两个数组中,以改进当前解决方案的(2 个数组 * N 个字段 * N 个潜在错误 = O( 2n^2) 表现。
6)忽略长样式的“<Form.Field control={Radio}>
”符号,您可以使用较短的 <Input>, <Button>, <Radio>,
等样式。此语法与验证无关。也忽略 div。
import React, { Component } from 'react'
import { Button, Checkbox, Form, Input, Radio, Select, Message, Label } from 'semantic-ui-react'
import * as yup from 'yup';
const options = [
{ text: 'buy', value: 'buy' },
{ text: 'sell', value: 'sell' },
]
class OrderEntryV3 extends Component {
state = {
errorPaths:[],
errors:[]
}
constructor(props){
super(props);
}
schema = yup.object().shape({
quantity: yup.number().required().positive().integer(),
price: yup.number().required().positive(),
marketSide: yup.string().required(),
orderType : yup.string().required()
});
handleChange = (e, component) => {
this.setState({[component.name]:component.value}, ()=>this.schema.validate(this.state, {abortEarly:false})
.then(valid=>this.setState({errorPaths:[], errors:[]})) //called if the entire form is valid
.catch(err=>this.setState({errors:err.errors, errorPaths: err.inner.map(i=>i.path) }))) //called if any field is invalid
};
render() {
return (
<div id="oeform-content">
<div id="oeform-left">
<Form>
<Form.Field error={this.state.errorPaths.includes('marketSide')} name="marketSide" control={Select} label='Market side' options={options} placeholder='market side' onChange={this.handleChange}/>
<Form.Field error={this.state.errorPaths.includes('quantity')} type='number' name="quantity" control={Input} label='Quantity' placeholder='quantity' onChange={this.handleChange}/>
<Form.Group>
<label><b>Order type</b></label>
<Form.Field error={this.state.errorPaths.includes('orderType')} >
<Radio
label='market'
name='orderType'
value='market'
checked={this.state.orderType === 'market'}
onChange={this.handleChange}
/>
</Form.Field>
<Form.Field error={this.state.errorPaths.includes('orderType')}>
<Radio
label='limit'
name='orderType'
value='limit'
checked={this.state.orderType === 'limit'}
onChange={this.handleChange}
/>
</Form.Field>
</Form.Group>
<Form.Field error={this.state.errorPaths.includes('price')} name='price' control={Input} type='number' label='Price' placeholder='price' onChange={this.handleChange}/>
<Form.Field control={Button} disabled={!!this.state.errors.length}>Submit</Form.Field>
<Message visible={!!this.state.errors.length} warning
header='Please correct the following issues: '
list={this.state.errors}/>
</Form>
</div>
<div id="oeform-right">
<p>{JSON.stringify(this.state)}</p>
</div>
</div>
)
}
}
export default OrderEntryV3
我们甚至有更好的选择,尽管语义-ui-react 没有提供 -> Formik + yup
Formik:帮助管理表单状态
是的:有助于验证该状态
我有下面的组件,它基本上是一个使用 semantic-ui-react 创建的编辑表单。
import React, { Component } from "react";
import { Button, Form, Modal, Message, Divider } from "semantic-ui-react";
import { Formik } from "formik";
import * as yup from "yup";
class EditAboutGrid extends Component {
render() {
const {
userBasic,
editBasicModal,
closeModal
} = this.props;
return (
<Formik
initialValues={{
firstName: userBasic.firstName,
lastName: userBasic.lastName,
bio: userBasic.bio,
}}
validationSchema={yup.object().shape({
firstName: yup
.string()
.required("Name cannot be empty"),
lastName: yup
.string()
.required("Name cannot be empty"),
bio: yup
.string()
.max(1000, "Maximum characters exceed 1000")
.nullable()
})}
onSubmit={(values, actions) => {
//do your stuff here like api calls
}}
render={({
values,
errors,
handleChange,
handleSubmit,
isSubmitting,
dirty,
setFieldValue
}) => (
<Modal open={editBasicModal} size="small">
<Modal.Header>Your basic details</Modal.Header>
<Modal.Content scrolling>
{errors.firstName && <Message error content={errors.firstName} />}
{errors.lastName && <Message error content={errors.lastName} />}
{errors.bio && <Message error content={errors.bio} />}
<Form loading={isSubmitting}>
<Form.Group inline widths="equal">
<Form.Input
required
label="First Name"
fluid
type="text"
name="firstName"
value={values.firstName}
onChange={handleChange}
error={errors.firstName !== undefined}
/>
<Form.Input
required
label="Last Name"
fluid
type="text"
name="lastName"
value={values.lastName}
onChange={handleChange}
error={errors.lastName !== undefined}
/>
</Form.Group>
<Form.TextArea
label="Bio"
type="text"
name="bio"
value={values.bio}
onChange={handleChange}
rows={3}
error={errors.bio !== undefined}
/>
</Form>
</Modal.Content>
<Modal.Actions open={true}>
<Button
onClick={() => (dirty ? closeModal(true) : closeModal(false))}>
Cancel
</Button>
<Button
primary
type="submit"
onClick={handleSubmit}
loading={isSubmitting}
disabled={isSubmitting || !isEmpty(errors) || !dirty}>
Update
</Button>
</Modal.Actions>
</Modal>
)}
/>
);
}
}
并且调用此表单使用:
<EditAboutGrid
editBasicModal={this.state.editBasicModal}
userBasic={this.state.user.basic}
closeModal={this.closeModal}
/>
initialValues
是事情开始的地方。在这里,您将 initial/default 值传递给表单的输入。 values
(in form) 将从该默认值中选取数据值。
validationSchema
是使用 yup
onSubmit
将在表单提交时调用。
使用 Formik + yup 处理表单非常简单。我很喜欢它。
我知道这已经有几年的历史了,并不是所问问题的完整解决方案,但今天看到的任何人都可能会发现这很有用,因为我一直在寻找相同的东西并且 运行 进入这个线程。虽然 semantic-ui-react 没有我能找到的表单验证,但它有一个很好的方式来显示表单验证错误。您仍然必须自己进行验证。请参阅 semantic-ui-react forms documentation page for an example of how it shows validation errors. It also has a feature to show success message. I have created an example 了解如何根据状态控制错误消息。在此示例中,您可以使用“显示性别错误”复选框来切换性别输入的错误消息。
对于语义验证形式-ui你可以简单地实现而不需要任何插件
<Form.Field
id='form-input-control-project-name'
control={Input}
label='Project Name'
placeholder='Project name'
onChange={this.handleChange}
error={this.state.projectName}
/>
this.state.projectName 在这个变量中你必须存储false/error消息
如果值为false不显示错误否则显示错误
我知道这个问题已经有好几年了,但这是我在使用(相对)较新的 React 功能组件和 Hooks 时遇到的困难 API。就我而言,我只是想验证用户输入的电子邮件地址是否有效。我最终通过下面的代码得到了我正在寻找的行为。
import React, {useState} from 'react';
import { Form } from 'semantic-ui-react'
import EmailValidator from 'email-validator';
function MyFormComponentExample() {
const [emailInput, setEmail] = useState("");
const [validEmail, validateEmail] = useState(true);
return (
<Form>
<Form.Input
icon='envelope'
iconPosition='left'
label='Email'
placeholder='Email Address'
required
value={emailInput}
onChange={e => {
setEmail(e.target.value);
validateEmail(EmailValidator.validate(e.target.value));
}}
error={validEmail ? false : {
content: 'Please enter a valid email address.',
pointing: 'below'
}}
/>
</Form>
);
}
export default MyFormComponentExample;
弄清楚后,我认为这个结构足够简单,但如果有人对执行此操作的更好模式或方法有任何反馈,我很乐意听到!
您可以使用 Formik 进行验证。
并且我创建了一个库来绑定 Formik 和 Semantic UI React。
https://github.com/JT501/formik-semantic-ui-react
一个简单的例子: Codesandbox