web-dev-qa-db-fra.com

React - Un composant enfant peut-il renvoyer une valeur au formulaire parent

InputField & Button sont des composants personnalisés qui vont dans un formulaire pour créer un formulaire. Mon problème est de savoir comment envoyer les données au formulaire de sorte que lors du clic sur le bouton, je puisse lancer ajax sur le formulaire avec des données (nom d'utilisateur et mot de passe):

export default auth.authApi(
  class SignUpViaEmail extends Component{

    constructor(props){
      super(props);
      this.state = {
        email : "",
        password : ""
      };
      this.storeEmail = this.storeEmail.bind( this );
      this.storePassword = this.storePassword.bind( this );
    }

    storeEmail(e){
      this.setState({ email : e.target.value });
    }

    storePassword(e){
      this.setState({ password : e.target.value });
    }

    handleSignUp(){
      this.props.handleSignUp(this.state);
    }

    render(){
      return(
        <div className="pageContainer">

          <form action="" method="post">
            <InputField labelClass = "label"
                        labelText = "Username"
                        inputId = "signUp_username"
                        inputType = "email"
                        inputPlaceholder = "registered email"
                        inputClass = "input" />
            <Button btnClass = "btnClass"
                    btnLabel = "Submit"
                    onClickEvent = { handleSignUp } />
          </form>
        </div>
      );
    }

  }
);

Ou n'est-il pas recommandé et je ne devrais pas créer de composants enfants personnalisés dans le formulaire?

composant enfant => InputField

import React,
       { Component } from "react";

export class InputField extends Component{

  constructor( props ){
    super( props );
    this.state = {
      value : ""
    };
    this.onUserInput = this.onUserInput.bind( this );
  }

  onUserInput( e ){
    this.setState({ value : e.target.value });
    this.props.storeInParentState({[ this.props.inputType ] : e.target.value });
  }

  render(){
    return  <div className = "">
              <label htmlFor = {this.props.inputId}
                     className = {this.props.labelClass}>
                {this.props.labelText}
              </label>
              <input id = {this.props.inputId}
                     type = {this.props.inputType}
                     onChange = {this.onUserInput} />
              <span className = {this.props.validationClass}>
                { this.props.validationNotice }
              </span>
            </div>;
  }
}

Erreur: j'obtiens l'erreur e.target is undefined sur la fonction parent storeEmail.

14
Kayote

Le modèle de liaison de données à sens unique de React signifie que les composants enfants ne peuvent pas renvoyer de valeurs aux composants parents sauf autorisation explicite . La manière React de procéder consiste à transmettre un rappel au composant enfant (voir Guide "Formulaires" de Facebook ).

class Parent extends Component {
  constructor() {
    this.state = {
      value: ''
    };
  }

  //...

  handleChangeValue = e => this.setState({value: e.target.value});

  //...

  render() {
    return (
      <Child
        value={this.state.value}
        onChangeValue={this.handleChangeValue}
      />
    );
  }
}

class Child extends Component {
  //...

  render() {
    return (
      <input
        type="text"
        value={this.props.value}
        onChange={this.props.onChangeValue}
      />
    );
  }
}

Notez que le composant parent gère l'état, tandis que le composant enfant ne gère que l'affichage . le guide "Lifting State Up" de Facebook est une bonne ressource pour apprendre à le faire.

De cette façon, toutes les données vivent dans le composant parent (dans l'état), et les composants enfants ne reçoivent qu'un moyen de mettre à jour ces données (rappels transmis comme accessoires) . Votre problème est maintenant résolu: votre composant parent a accès à toutes les données dont il a besoin (car les données sont stockées dans l'état), mais vos composants enfants sont chargés de lier les données à leurs propres éléments individuels, tels que <input> Mots clés.

40
Ian Emnace

Parent

import React, { Component } from 'react';
import Child from './child'
class Parent extends Component {
  state = {
    value: ''
  }
  onChangeValueHandler = (val) => {
    this.setState({ value: val.target.value })
  }
  render() {
    const { value } = this.state;
    return (
      <div>
        <p> the value is : {value} </p>
        <Child value={value} onChangeValue={this.onChangeValueHandler} />
      </div>
    );
  }
}

export default Parent;

Enfant

  import React, { Component } from 'react';
  class Child extends Component {
  render() {
  const { value , onChangeValue } = this.props;
  return (
    <div>
      <input type="text"  value={value} onChange={onChangeValue}/> 
    </div>
  );
}
}
  export default Child;

vous pouvez voir l'exemple en direct sur: https://codesandbox.io/s/two-way-binding-qq1o1?from-embed

0
Ali Mohammad