Je suis un débutant en reactjs. Je me sens très bien à l'idée de l'utiliser, mais je suis bloqué depuis un moment sur un concept que je veux mettre en œuvre, qui résoudrait tout un tas d'autres problèmes.
Concept
- Je souhaite créer un composant de formulaire qui peut recevoir des enfants dynamiques. Il ne s'agira pas d'un composant de formulaire spécifique comme Formulaire de connexion, Formulaire de contact etc. Il s'agirait plutôt de Formulaire .
Approche 1
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 appelle la fonction validate qui transmet simplement les arguments à la fonction validate du formulaire. Pour que le formulaire sache si tous ses enfants sont validés. Je passe isValid et targetInputComponent comme arguments au formulaire.
- Le bouton Submit onClick appelle la fonction submit de la même manière et LoginPage (qui joue le rôle d'intergiciel) transmet l'appel au composant Form. Le formulaire vérifie l'état des entrées inValid, etc.
- L'appel onClick de la réinitialisation du bouton est transmis au composant Form de la même manière. Mais comment le formulaire gère-t-il cette fonctionnalité de réinitialisation ? La valeur de l'entrée est contrôlée par la page de connexion. Le formulaire ne peut pas modifier la valeur de l'entrée.
Approche 2
Ce que j'ai fait, c'est ajouter les données et la validité de l'entrée à l'état de la page de connexion. Désormais, les composants Form et Inputs appellent simplement la page de connexion pour mettre à jour son état. Les composants Form et Inputs utilisent cet état comme 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>
}
}
Problème
Cette approche rend le composant LoginPage assez désordonné. Comment le composant LoginPage va-t-il gérer les formulaires si j'ai plus d'un formulaire sur la page ? Il y aura encore plus de fonctionnalités dans la LoginPage, comme les listes, les grilles, les fenêtres modales, etc. Cette page de connexion ne devrait pas gérer ces situations. Formulaire devrait être responsable de toutes les fonctionnalités d'entrée, de soumission, etc. Ce composant de formulaire doit être générique pour tous les types de formulaires. Je ne veux pas créer des formulaires de type LoginForm, ContactForm, etc.
La solution à cette question me sera d'une grande aide dans bien d'autres domaines.