提交 React 表单后如何清除 Bootstrap 4 个错误?
How do I clear Bootstrap 4 errors after I submit my React form?
我将 React 16.13.0 与 Bootstrap 4 一起使用。我创建了以下组件,我在我的 React 表单中使用了...
const Input = (props) => {
return (
<div className="form-group">
<FormLabel>{props.title}</FormLabel>
<FormControl
isInvalid={props.errors && Boolean(props.errors[props.name])}
type={props.type}
id={props.name}
name={props.name}
value={props.value}
placeholder={props.placeholder}
onChange={props.handleChange}
/>
{props.errors && props.errors[props.name] && (
<FormControl.Feedback type="invalid">
{props.errors[props.name].map((error, index) => (
<div key={`field-error-${props.name}-${index}`} className="fieldError">{error}</div>
))}
</FormControl.Feedback>
)}
</div>
)
}
export default Input;
下面是处理表单提交功能以及我创建表单的一些容器...
async handleFormSubmit(e) {
e.preventDefault();
const NC = this.state.newCoop;
delete NC.address.country;
try {
const response = await fetch(FormContainer.REACT_APP_PROXY + '/coops/',{
method: "POST",
body: JSON.stringify(this.state.newCoop),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
});
if (response.ok) {
const result = await response.json();
window.flash('Record has been created successfully!', 'success')
return result;
}
throw await response.json();
} catch (errors) {
console.log('_error_: ', errors);
this.setState({ errors });
}
}
...
render() {
if (this.state.coopTypes && !this.state.coopTypes.length) {
return null;
}
return (
<div>
<form className="container-fluid" onSubmit={this.handleFormSubmit}>
<FormGroup
controlId="formBasicText">
<Input inputType={'text'}
title= {'Name'}
name= {'name'}
value={this.state.newCoop.name}
placeholder = {'Enter cooperative name'}
handleChange = {this.handleInput}
errors = {this.state.errors}
/> {/* Name of the cooperative */}
问题是,在我提交表单后,如果之前 运行 出现错误,它们仍会显示在屏幕上。
在成功提交表单后,是否有清除 Bootstrap 错误显示的标准方法?
由于您正在使用 this.state.errors
向 <Input>
组件提供错误信息 prop,您只需更新 handleInput(...)
函数以在您的 this.state.errors
时清除 this.state.errors
输入值变化。这个想法是这样的:
handleInput = (event) => {
const errors = Object.assign({}, this.state.errors);
const target = event.target;
// remove the error value for a specific input only
delete errors[target.name];
this.setState({ errors });
// Do whatever else needs to be done here for your input
}
这是一个工作示例:https://jsfiddle.net/4gqr0cfa/
您需要根据表单是否有效来添加或删除表单验证。为此,请在最初设置为 false 的 Form
上添加 validated
属性。
我怎样才能让它发挥作用?
按照以下步骤操作:
在包含 Form
的组件中创建一个布尔状态变量,其初始值应为 false。
const [validated, setValidated] = useState(false);
在表单上添加一个名为 validated
的属性,并将其值设置为等于在步骤 1 中创建的布尔状态变量。
<Form validated={validated}>
...
</Form>
提交表单时,检查表单是否有效,如果有效,则将状态变量validated
设置为true
。
这是一个工作演示
function App() {
const [ validated, setValidated ] = React.useState(false);
const [ form, setForm ] = React.useState({
fields: {
name: { type: 'text', value: '', title: 'Name' },
email: { type: 'email', value: '', title: 'Email' },
password: { type: 'password', value: '', title: 'Password' }
},
errors: {}
});
const handleSubmit = (event) => {
event.preventDefault();
const errors = {};
let invalid = false;
Object.entries(form.fields).forEach(([k, v]) => {
if (!errors[k]) errors[k] = [];
if (!v.value) {
errors[k].push(`${k} is required`);
invalid = true;
}
if (k === 'email' && !v.value.includes('@')) {
errors[k].push('enter a valid email address');
invalid = true;
}
if (k === 'password' && v.value.length < 8) {
errors[k].push('password should be atleast 8 characters long');
invalid = true;
}
});
setForm({ ...form, errors });
if (invalid) {
setValidated(false);
} else {
setValidated(true);
}
};
const handleChange = ({ target }) => {
const updatedField = { ...form.fields[target.name], value: target.value };
const fields = {
...form.fields,
[target.name]: updatedField
};
setForm({ ...form, fields });
};
return (
<div style={{ maxWidth: '300px', margin: '10px auto'}}>
<ReactBootstrap.Form noValidate validated={validated} onSubmit={handleSubmit}>
{
Object.entries(form.fields).map(([k, v]) => {
return (
<Input
key={k}
title={v.title}
type={v.type}
name={k}
value={v.value}
placeholder={v.title}
handleChange={handleChange}
errors={form.errors}
/>
);
})
}
<ReactBootstrap.Button type="submit">Submit form</ReactBootstrap.Button>
</ReactBootstrap.Form>
</div>
);
}
const Input = (props) => {
return (
<ReactBootstrap.Form.Group>
<ReactBootstrap.FormLabel>{props.title}</ReactBootstrap.FormLabel>
<ReactBootstrap.FormControl
isInvalid={
Array.isArray(props.errors[props.name])
? props.errors[props.name].length > 0
? true : false
: false
}
type={props.type}
id={props.name}
name={props.name}
value={props.value}
placeholder={props.placeholder}
onChange={props.handleChange}
/>
{props.errors && props.errors[props.name] && (
<ReactBootstrap.FormControl.Feedback type="invalid">
{props.errors[props.name].map((error, index) => (
<div key={`field-error-${props.name}-${index}`} className="fieldError">{error}</div>
))}
</ReactBootstrap.FormControl.Feedback>
)}
</ReactBootstrap.Form.Group>
)
}
ReactDOM.render(<App />, document.getElementById('root'));
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-bootstrap/1.1.0-rc.0/react-bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.min.js"></script>
<div id="root"></div>
您也可以在 stackblitz
上观看相同的演示
您可以改进上述演示,通过使用 is-valid
和 is-invalid
类 分别添加绿色或红色边框来向用户指示输入字段有效或无效。
function App() {
const [ validated, setValidated ] = React.useState(false);
const [ form, setForm ] = React.useState({
fields: {
name: { type: 'text', value: '', title: 'Name' },
email: { type: 'email', value: '', title: 'Email' },
password: { type: 'password', value: '', title: 'Password' }
},
errors: {}
});
const handleSubmit = (event) => {
event.preventDefault();
const errors = {};
let invalid = false;
Object.entries(form.fields).forEach(([k, v]) => {
if (!errors[k]) errors[k] = [];
if (!v.value) {
errors[k].push(`${k} is required`);
invalid = true;
}
if (k === 'email' && !v.value.includes('@')) {
errors[k].push('enter a valid email address');
invalid = true;
}
if (k === 'password' && v.value.length < 8) {
errors[k].push('password should be atleast 8 characters long');
invalid = true;
}
});
setForm({ ...form, errors });
if (invalid) {
setValidated(false);
} else {
setValidated(true);
}
};
const handleChange = ({ target }) => {
const updatedField = { ...form.fields[target.name], value: target.value };
const fields = {
...form.fields,
[target.name]: updatedField
};
setForm({ ...form, fields });
};
return (
<div style={{ maxWidth: '300px', margin: '10px auto'}}>
<ReactBootstrap.Form noValidate validated={validated} onSubmit={handleSubmit}>
{
Object.entries(form.fields).map(([k, v]) => {
return (
<Input
key={k}
title={v.title}
type={v.type}
name={k}
value={v.value}
placeholder={v.title}
handleChange={handleChange}
errors={form.errors}
/>
);
})
}
<ReactBootstrap.Button type="submit">Submit form</ReactBootstrap.Button>
</ReactBootstrap.Form>
</div>
);
}
const Input = (props) => {
return (
<ReactBootstrap.Form.Group>
<ReactBootstrap.FormLabel>{props.title}</ReactBootstrap.FormLabel>
<ReactBootstrap.FormControl
isInvalid={
Array.isArray(props.errors[props.name])
? props.errors[props.name].length > 0
? true : false
: false
}
type={props.type}
id={props.name}
name={props.name}
value={props.value}
placeholder={props.placeholder}
onChange={props.handleChange}
className={
Array.isArray(props.errors[props.name])
? props.errors[props.name].length > 0 ? 'is-invalid': 'is-valid'
: ''
}
/>
{props.errors && props.errors[props.name] && (
<ReactBootstrap.FormControl.Feedback type="invalid">
{props.errors[props.name].map((error, index) => (
<div key={`field-error-${props.name}-${index}`} className="fieldError">{error}</div>
))}
</ReactBootstrap.FormControl.Feedback>
)}
</ReactBootstrap.Form.Group>
)
}
ReactDOM.render(<App />, document.getElementById('root'));
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-bootstrap/1.1.0-rc.0/react-bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.min.js"></script>
<div id="root"></div>
上查看此演示
您可以在 react-bootstrap and bootstrap
的官方文档中阅读 bootstrap 中的表单验证
我将 React 16.13.0 与 Bootstrap 4 一起使用。我创建了以下组件,我在我的 React 表单中使用了...
const Input = (props) => {
return (
<div className="form-group">
<FormLabel>{props.title}</FormLabel>
<FormControl
isInvalid={props.errors && Boolean(props.errors[props.name])}
type={props.type}
id={props.name}
name={props.name}
value={props.value}
placeholder={props.placeholder}
onChange={props.handleChange}
/>
{props.errors && props.errors[props.name] && (
<FormControl.Feedback type="invalid">
{props.errors[props.name].map((error, index) => (
<div key={`field-error-${props.name}-${index}`} className="fieldError">{error}</div>
))}
</FormControl.Feedback>
)}
</div>
)
}
export default Input;
下面是处理表单提交功能以及我创建表单的一些容器...
async handleFormSubmit(e) {
e.preventDefault();
const NC = this.state.newCoop;
delete NC.address.country;
try {
const response = await fetch(FormContainer.REACT_APP_PROXY + '/coops/',{
method: "POST",
body: JSON.stringify(this.state.newCoop),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
});
if (response.ok) {
const result = await response.json();
window.flash('Record has been created successfully!', 'success')
return result;
}
throw await response.json();
} catch (errors) {
console.log('_error_: ', errors);
this.setState({ errors });
}
}
...
render() {
if (this.state.coopTypes && !this.state.coopTypes.length) {
return null;
}
return (
<div>
<form className="container-fluid" onSubmit={this.handleFormSubmit}>
<FormGroup
controlId="formBasicText">
<Input inputType={'text'}
title= {'Name'}
name= {'name'}
value={this.state.newCoop.name}
placeholder = {'Enter cooperative name'}
handleChange = {this.handleInput}
errors = {this.state.errors}
/> {/* Name of the cooperative */}
问题是,在我提交表单后,如果之前 运行 出现错误,它们仍会显示在屏幕上。
在成功提交表单后,是否有清除 Bootstrap 错误显示的标准方法?
由于您正在使用 this.state.errors
向 <Input>
组件提供错误信息 prop,您只需更新 handleInput(...)
函数以在您的 this.state.errors
时清除 this.state.errors
输入值变化。这个想法是这样的:
handleInput = (event) => {
const errors = Object.assign({}, this.state.errors);
const target = event.target;
// remove the error value for a specific input only
delete errors[target.name];
this.setState({ errors });
// Do whatever else needs to be done here for your input
}
这是一个工作示例:https://jsfiddle.net/4gqr0cfa/
您需要根据表单是否有效来添加或删除表单验证。为此,请在最初设置为 false 的 Form
上添加 validated
属性。
我怎样才能让它发挥作用?
按照以下步骤操作:
在包含
Form
的组件中创建一个布尔状态变量,其初始值应为 false。const [validated, setValidated] = useState(false);
在表单上添加一个名为
validated
的属性,并将其值设置为等于在步骤 1 中创建的布尔状态变量。<Form validated={validated}> ... </Form>
提交表单时,检查表单是否有效,如果有效,则将状态变量
validated
设置为true
。
这是一个工作演示
function App() {
const [ validated, setValidated ] = React.useState(false);
const [ form, setForm ] = React.useState({
fields: {
name: { type: 'text', value: '', title: 'Name' },
email: { type: 'email', value: '', title: 'Email' },
password: { type: 'password', value: '', title: 'Password' }
},
errors: {}
});
const handleSubmit = (event) => {
event.preventDefault();
const errors = {};
let invalid = false;
Object.entries(form.fields).forEach(([k, v]) => {
if (!errors[k]) errors[k] = [];
if (!v.value) {
errors[k].push(`${k} is required`);
invalid = true;
}
if (k === 'email' && !v.value.includes('@')) {
errors[k].push('enter a valid email address');
invalid = true;
}
if (k === 'password' && v.value.length < 8) {
errors[k].push('password should be atleast 8 characters long');
invalid = true;
}
});
setForm({ ...form, errors });
if (invalid) {
setValidated(false);
} else {
setValidated(true);
}
};
const handleChange = ({ target }) => {
const updatedField = { ...form.fields[target.name], value: target.value };
const fields = {
...form.fields,
[target.name]: updatedField
};
setForm({ ...form, fields });
};
return (
<div style={{ maxWidth: '300px', margin: '10px auto'}}>
<ReactBootstrap.Form noValidate validated={validated} onSubmit={handleSubmit}>
{
Object.entries(form.fields).map(([k, v]) => {
return (
<Input
key={k}
title={v.title}
type={v.type}
name={k}
value={v.value}
placeholder={v.title}
handleChange={handleChange}
errors={form.errors}
/>
);
})
}
<ReactBootstrap.Button type="submit">Submit form</ReactBootstrap.Button>
</ReactBootstrap.Form>
</div>
);
}
const Input = (props) => {
return (
<ReactBootstrap.Form.Group>
<ReactBootstrap.FormLabel>{props.title}</ReactBootstrap.FormLabel>
<ReactBootstrap.FormControl
isInvalid={
Array.isArray(props.errors[props.name])
? props.errors[props.name].length > 0
? true : false
: false
}
type={props.type}
id={props.name}
name={props.name}
value={props.value}
placeholder={props.placeholder}
onChange={props.handleChange}
/>
{props.errors && props.errors[props.name] && (
<ReactBootstrap.FormControl.Feedback type="invalid">
{props.errors[props.name].map((error, index) => (
<div key={`field-error-${props.name}-${index}`} className="fieldError">{error}</div>
))}
</ReactBootstrap.FormControl.Feedback>
)}
</ReactBootstrap.Form.Group>
)
}
ReactDOM.render(<App />, document.getElementById('root'));
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-bootstrap/1.1.0-rc.0/react-bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.min.js"></script>
<div id="root"></div>
您也可以在 stackblitz
上观看相同的演示您可以改进上述演示,通过使用 is-valid
和 is-invalid
类 分别添加绿色或红色边框来向用户指示输入字段有效或无效。
function App() {
const [ validated, setValidated ] = React.useState(false);
const [ form, setForm ] = React.useState({
fields: {
name: { type: 'text', value: '', title: 'Name' },
email: { type: 'email', value: '', title: 'Email' },
password: { type: 'password', value: '', title: 'Password' }
},
errors: {}
});
const handleSubmit = (event) => {
event.preventDefault();
const errors = {};
let invalid = false;
Object.entries(form.fields).forEach(([k, v]) => {
if (!errors[k]) errors[k] = [];
if (!v.value) {
errors[k].push(`${k} is required`);
invalid = true;
}
if (k === 'email' && !v.value.includes('@')) {
errors[k].push('enter a valid email address');
invalid = true;
}
if (k === 'password' && v.value.length < 8) {
errors[k].push('password should be atleast 8 characters long');
invalid = true;
}
});
setForm({ ...form, errors });
if (invalid) {
setValidated(false);
} else {
setValidated(true);
}
};
const handleChange = ({ target }) => {
const updatedField = { ...form.fields[target.name], value: target.value };
const fields = {
...form.fields,
[target.name]: updatedField
};
setForm({ ...form, fields });
};
return (
<div style={{ maxWidth: '300px', margin: '10px auto'}}>
<ReactBootstrap.Form noValidate validated={validated} onSubmit={handleSubmit}>
{
Object.entries(form.fields).map(([k, v]) => {
return (
<Input
key={k}
title={v.title}
type={v.type}
name={k}
value={v.value}
placeholder={v.title}
handleChange={handleChange}
errors={form.errors}
/>
);
})
}
<ReactBootstrap.Button type="submit">Submit form</ReactBootstrap.Button>
</ReactBootstrap.Form>
</div>
);
}
const Input = (props) => {
return (
<ReactBootstrap.Form.Group>
<ReactBootstrap.FormLabel>{props.title}</ReactBootstrap.FormLabel>
<ReactBootstrap.FormControl
isInvalid={
Array.isArray(props.errors[props.name])
? props.errors[props.name].length > 0
? true : false
: false
}
type={props.type}
id={props.name}
name={props.name}
value={props.value}
placeholder={props.placeholder}
onChange={props.handleChange}
className={
Array.isArray(props.errors[props.name])
? props.errors[props.name].length > 0 ? 'is-invalid': 'is-valid'
: ''
}
/>
{props.errors && props.errors[props.name] && (
<ReactBootstrap.FormControl.Feedback type="invalid">
{props.errors[props.name].map((error, index) => (
<div key={`field-error-${props.name}-${index}`} className="fieldError">{error}</div>
))}
</ReactBootstrap.FormControl.Feedback>
)}
</ReactBootstrap.Form.Group>
)
}
ReactDOM.render(<App />, document.getElementById('root'));
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-bootstrap/1.1.0-rc.0/react-bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.min.js"></script>
<div id="root"></div>
您可以在 react-bootstrap and bootstrap
的官方文档中阅读 bootstrap 中的表单验证