React JS - 用动态子元素组合通用形式
React JS - Composing generic form with dynamic childrens
我只是reactjs的初学者。我对使用它感觉非常好,但我已经坚持了一段时间我想实现的概念,这将解决我所有其他问题。
概念
- 我想创建一个可以向其传递动态 children 的表单组件。它不会是特定的表单组件,如 LoginForm、ContactForm 等。它只是 Form。
方法一
class LoginPage extends Rect.Component {
constructor(props) {
super(props)
this.submit = this.submit.bind(this);
this.validate = this.validate.bind(this);
this.reset = this.reset.bind(this);
}
submit(...args) {
this.refs.form.submit(args);
}
validate(...args) {
this.refs.form.validate(args);
}
reset(...args) {
this.refs.form.reset(args);
}
render() {
return (
<LoginPage>
<Form ref="form" onSubmit={this.submit}>
<Input value="email" pattern="/email_pattern/" onValidate={this.validate} />
<Input value="password" pattern="/password_pattern/" onValidate={this.validate} />
<Button value="submit" action={this.submit} />
<Button value="reset" action={this.reset} />
</Form>
</LoginPage>
}
}
- Input onChange 调用仅将参数传递给表单的验证函数的验证函数。为了让表单知道它的所有 children 是否都经过验证。我将 isValid 和 targetInputComponent 作为参数传递给表单。
- Button Submit onClick 同样调用提交函数,LoginPage(充当中间件)将调用传递给 Form 组件。表单检查它的状态是否有无效输入等。
- 按钮重置 onClick 调用同样传递给表单组件。但是表单如何处理这个重置功能呢? Input 的值由 LoginPage 控制。表单无法更改输入的值。
方法 2
我所做的是将输入的数据和有效性添加到 LoginPage 状态。现在 Form 和 Inputs 都只是调用登录页面来更新它的状态。 Form 和 Inputs 组件使用这个状态作为 prop。
class LoginPage extends React.Component {
constructor(props) {
super(props)
this.state = {
formSchema: this.initSchema()
}
this.validateField = this.validateField.bind(this);
this.submitForm = this.submitForm.bind(this);
}
initSchema() {
const formSchema = {
email: {
isValid: false,
value: ''
},
password: {
isValid: false,
value: ''
},
password2: {
isValid: false,
value: ''
}
}
return formSchema;
}
validateField(dataObj, targetComponent) {
const formSchema = Object.assign(this.state.formSchema, dataObj);
this.setState({ formSchema })
}
submitForm(isSuccess) {
console.log(isSuccess);
console.log('Form Submit: ', this.state.formSchema);
throw new Error('Submition Error');
}
reset() {
// Loop through each object in formSchema and set it's value to empty, inputs will validate themselves automatically.
}
render() {
return <div>
<Form ref="formLogin" className="auth-form" onSubmit={this.submitForm} formSchema={this.state.formSchema}>
<h1>
Switch Accounts
</h1>
<Input type="email" name="email" onValidate={this.validateField} value={this.state.formSchema.email.value}
isValid={this.state.formSchema.email.isValid}/>
<Input type="password" name="password" onValidate={this.validateField} value={this.state.formSchema.password.value}
isValid={this.state.formSchema.password.isValid}/>
<Button value="Submit" type="submit" />
</Form>
</div>
}
}
问题
这种方法使登录页面组件变得非常混乱。如果页面上有多个表单,LoginPage 组件将如何处理这些表单? LoginPage 将有更多功能,如列表、网格、模式等。此 LoginPage 不应处理这些情况。 Form 应负责所有输入、提交等功能。这个表单组件应该对所有类型的表单都是通用的。我不想创建 LoginForm、ContactForm 等功能表单
这个问题的解决方案将在很多其他方面对我有很大帮助。
您的方法 2 是处理此问题的标准方法。
您为什么不创建一个单独的 <LoginForm>
?这样做可以将字段和验证从页面上的其他不相关功能中抽象出来。
如果以后您需要 <ContactForm>
或任何其他类型的表单,它将具有不同的字段和不同的验证逻辑,这意味着无论如何您都需要构建它。
除了使用 redux
之类的东西,你的方向是正确的。
制作“通用”表格的方法有很多种。但在我看来,最好将表格分开保存。
我之所以这样说,是因为无论如何,您仍然必须为大多数字段实施各种验证条件,例如电子邮件地址或您将使用的任何内容。
我认为最好的方法是使组件独立。例如:创建一个 TextField 组件来处理诸如验证之类的输入内容。可能是用于提交和回调的 Button 组件。
所以我的建议是:将表格分开。无需过度思考和浪费有用的时间来尝试让事情变得“漂亮”。
祝你好运!
我只是reactjs的初学者。我对使用它感觉非常好,但我已经坚持了一段时间我想实现的概念,这将解决我所有其他问题。
概念
- 我想创建一个可以向其传递动态 children 的表单组件。它不会是特定的表单组件,如 LoginForm、ContactForm 等。它只是 Form。
方法一
class LoginPage extends Rect.Component {
constructor(props) {
super(props)
this.submit = this.submit.bind(this);
this.validate = this.validate.bind(this);
this.reset = this.reset.bind(this);
}
submit(...args) {
this.refs.form.submit(args);
}
validate(...args) {
this.refs.form.validate(args);
}
reset(...args) {
this.refs.form.reset(args);
}
render() {
return (
<LoginPage>
<Form ref="form" onSubmit={this.submit}>
<Input value="email" pattern="/email_pattern/" onValidate={this.validate} />
<Input value="password" pattern="/password_pattern/" onValidate={this.validate} />
<Button value="submit" action={this.submit} />
<Button value="reset" action={this.reset} />
</Form>
</LoginPage>
}
}
- Input onChange 调用仅将参数传递给表单的验证函数的验证函数。为了让表单知道它的所有 children 是否都经过验证。我将 isValid 和 targetInputComponent 作为参数传递给表单。
- Button Submit onClick 同样调用提交函数,LoginPage(充当中间件)将调用传递给 Form 组件。表单检查它的状态是否有无效输入等。
- 按钮重置 onClick 调用同样传递给表单组件。但是表单如何处理这个重置功能呢? Input 的值由 LoginPage 控制。表单无法更改输入的值。
方法 2
我所做的是将输入的数据和有效性添加到 LoginPage 状态。现在 Form 和 Inputs 都只是调用登录页面来更新它的状态。 Form 和 Inputs 组件使用这个状态作为 prop。
class LoginPage extends React.Component {
constructor(props) {
super(props)
this.state = {
formSchema: this.initSchema()
}
this.validateField = this.validateField.bind(this);
this.submitForm = this.submitForm.bind(this);
}
initSchema() {
const formSchema = {
email: {
isValid: false,
value: ''
},
password: {
isValid: false,
value: ''
},
password2: {
isValid: false,
value: ''
}
}
return formSchema;
}
validateField(dataObj, targetComponent) {
const formSchema = Object.assign(this.state.formSchema, dataObj);
this.setState({ formSchema })
}
submitForm(isSuccess) {
console.log(isSuccess);
console.log('Form Submit: ', this.state.formSchema);
throw new Error('Submition Error');
}
reset() {
// Loop through each object in formSchema and set it's value to empty, inputs will validate themselves automatically.
}
render() {
return <div>
<Form ref="formLogin" className="auth-form" onSubmit={this.submitForm} formSchema={this.state.formSchema}>
<h1>
Switch Accounts
</h1>
<Input type="email" name="email" onValidate={this.validateField} value={this.state.formSchema.email.value}
isValid={this.state.formSchema.email.isValid}/>
<Input type="password" name="password" onValidate={this.validateField} value={this.state.formSchema.password.value}
isValid={this.state.formSchema.password.isValid}/>
<Button value="Submit" type="submit" />
</Form>
</div>
}
}
问题
这种方法使登录页面组件变得非常混乱。如果页面上有多个表单,LoginPage 组件将如何处理这些表单? LoginPage 将有更多功能,如列表、网格、模式等。此 LoginPage 不应处理这些情况。 Form 应负责所有输入、提交等功能。这个表单组件应该对所有类型的表单都是通用的。我不想创建 LoginForm、ContactForm 等功能表单
这个问题的解决方案将在很多其他方面对我有很大帮助。
您的方法 2 是处理此问题的标准方法。
您为什么不创建一个单独的 <LoginForm>
?这样做可以将字段和验证从页面上的其他不相关功能中抽象出来。
如果以后您需要 <ContactForm>
或任何其他类型的表单,它将具有不同的字段和不同的验证逻辑,这意味着无论如何您都需要构建它。
除了使用 redux
之类的东西,你的方向是正确的。
制作“通用”表格的方法有很多种。但在我看来,最好将表格分开保存。
我之所以这样说,是因为无论如何,您仍然必须为大多数字段实施各种验证条件,例如电子邮件地址或您将使用的任何内容。
我认为最好的方法是使组件独立。例如:创建一个 TextField 组件来处理诸如验证之类的输入内容。可能是用于提交和回调的 Button 组件。
所以我的建议是:将表格分开。无需过度思考和浪费有用的时间来尝试让事情变得“漂亮”。
祝你好运!