【发布时间】:2019-06-15 15:40:57
【问题描述】:
// App.js
import React, { Component } from 'react';
import './App.css';
import fields from './fields'
import CustomInputType from './custominputtype'
class App extends Component {
state = {
formData: {},
fieldErrorStatus: {},
submitErrorStatus: false
}
handleChange = (e) => {
// adding the new on change value to the corresponding field name
const { name, value } = e.target;
const tempObj = { ...this.state.formData };
tempObj[name] = value;
this.setState({ formData: tempObj });
// adding the error status for the corresponding field name
let tempErrorStatus = { ...this.state.fieldErrorStatus }
tempErrorStatus[name] = false;
this.setState({ fieldErrorStatus: tempErrorStatus })
};
handleSubmit = (e) => {
let formValues = this.state.formData;
if (Object.keys(formValues).length === 0) {
this.setState({ submitErrorStatus: true })
}
else {
let tempErrorStatus = {};
this.setState({ submitErrorStatus: false });
Object.keys(formValues).forEach(key => {
if (formValues[key]) {
tempErrorStatus[key] = false;
}
})
this.setState(prevState => {
return {
fieldErrorStatus: { ...prevState.fieldErrorStatus, tempErrorStatus }
}
})
}
e.preventDefault();
}
render() {
return (
<div className="form">
<form
onSubmit={this.handleSubmit}
onChange={(e) => this.handleChange(e)}
>
<div className="inputs-collection">
{
fields[0].attributes.map((field, i) => {
return (
<CustomInputType
attributes={field}
key={i}
value={this.state.formData[i]}
obj={this.state.formData}
errorStatus={this.state.fieldErrorStatus}
displayError={this.state.submitErrorStatus}
/>
)
})
}
</div>
<div className="button-container">
<button className="submit-button" type="submit">Submit Details</button>
</div>
</form>
</div>
)
}
}
export default App;
// CustomInputType
import React , {Component} from 'react'
class CustomInputType extends Component {
render(){
const {
attributes: {
id,
name,
dataType,
} = {},
displayError,
obj,
errorStatus
} = this.props;
return (
<div className="input-container">
<label htmlFor={id}>
{name}
</label>
<input
type={dataType}
name={name || ''}
value={obj[name]}
id={id}
/>
{
displayError || Boolean(errorStatus[name]) ?
<span>{`Error on ${name}`}</span> : null
}
</div>
)
}
}
export default CustomInputType
// fields
let fields = [
{
"id": "1",
"name": "Form 1",
"type": "Dynamic Form",
"attributes": [
{
"name": "First Name",
"dataType": "String",
"id": 101,
},
{
"name": "Surname",
"dataType": "String",
"id": 102,
},
{
"name": "Phone Number",
"dataType": "Number",
"id": 103,
},
{
"name": "Roll Number",
"dataType": "Number",
"id": 104,
}
]
}
];
export default fields;
我有一个父组件,我在本地读取一个 json 文件并渲染字段,基本上我有一个子组件,它是一个自定义输入类型组件。
在我的子组件中有一个称为错误的道具,它是一个布尔值。因此,如果它是真的,它将在该字段周围显示一个红色框。我需要显示红色框的案例是 onChange 、 onBlur 和 submit。 对于 sumbit,我在 state 中使用 submitErrorStatus 变量,对于 handleChange 和 onBlur,我使用 fieldErrorStatus。因此,当用户直接提交而没有任何字段进入redbox时应该会出现,一旦他键入每个字段或模糊redbox应该会消失。
我已经完成了以下操作,但有些地方令人困惑。
父组件
state = {
formData : {},
fieldErrorStatus : {},
submitErrorStatus : false
}
handleChange = (e) => {
// adding the new on change value to the corresponding field name
const { name, value} = e.target;
const tempObj = {...this.state.formData};
tempObj[name] = value;
this.setState({ formData:tempObj });
// adding the error status for the corresponding field name
let tempErrorStatus = {...this.state.fieldErrorStatus}
tempErrorStatus[name] = false;
this.setState({fieldErrorStatus:tempErrorStatus})
};
handleSubmit = (e) => {
let formValues = this.state.formData;
if(Object.keys(formValues).length === 0){
this.setState({submitErrorStatus: true})
}
else{
let tempErrorStatus = {};
this.setState({submitErrorStatus: false});
Object.keys(formValues).forEach(key => {
if(formValues[key]){
tempErrorStatus[key] = false;
}
})
this.setState(prevState => {
return {
fieldErrorStatus: {...prevState.fieldErrorStatus, tempErrorStatus}
}
})
}
e.preventDefault();
}
render(){
<div className = "form">
<form
onSubmit = {this.handleSubmit}
onChange = {(e) => this.handleChange(e)}
>
<div className = "inputs-collection">
{
fields.map((field, i) => {
return (
<InputTypes
attributes = {field}
key = {i}
value = {this.state.formData[i]}
obj = {this.state.formData}
errorStatus = {this.state.fieldErrorStatus}
displayError = {this.state.submitErrorStatus}
/>
)
})
}
</div>
<div className = "button-container">
<button className = "submit-button" type = "submit">Submit Details</button>
</div>
</form>
</div>
}
子组件
render(){
const {
attributes : {
id,
name,
dataType,
rules,
} = {},
displayError,
obj,
errorStatus
} = this.props;
return(
<div className="input-container">
<Input
type = {dataType}
id = {id.toString()}
name = {name || ''}
value = {obj[name]}
error={displayError || errorStatus[name] ? false : true} />
</div>
)
}
【问题讨论】:
-
嗯.. 你的问题到底是什么? “它只是不起作用”? :D
-
不,我有一个 json 文件,在其中我得到一个字段列表集合,我在父组件中获得,使用 map 方法我将属性,errorStatus 传递给子组件
-
所以当用户点击提交而不输入详细信息时,每个字段都会显示红色边框,一旦有值,红色边框就会消失,当用户在任何输入字段中进行 onBlur 和在不输入任何数据的情况下转到下一个字段应该出现红色边框
-
@Elias 问题是它是一个动态列表,这么多条件我应该满足任何想法
-
我会开始一个项目,把组件扔进去,看看我能做什么。
标签: javascript reactjs