web-dev-qa-db-fra.com

Comment passer des données du composant enfant à son parent dans ReactJS?

J'essaie d'envoyer les données d'un composant enfant à son parent comme suit:

const ParentComponent = React.createClass({
    getInitialState() {
        return {
            language: '',
        };
    },
    handleLanguageCode: function(langValue) {
        this.setState({language: langValue});
    },

    render() {
         return (
                <div className="col-sm-9" >
                    <SelectLanguage onSelectLanguage={this.handleLanguage}/> 
                </div>
        );
});

et voici le composant enfant:

export const SelectLanguage = React.createClass({
    getInitialState: function(){
        return{
            selectedCode: '',
            selectedLanguage: '',
        };
    },

    handleLangChange: function (e) {
        var lang = this.state.selectedLanguage;
        var code = this.state.selectedCode;
        this.props.onSelectLanguage({selectedLanguage: lang});   
        this.props.onSelectLanguage({selectedCode: code});           
    },

    render() {
        var json = require("json!../languages.json");
        var jsonArray = json.languages;
        return (
            <div >
                <DropdownList ref='dropdown'
                    data={jsonArray} 
                    value={this.state.selectedLanguage}
                    caseSensitive={false} 
                    minLength={3}
                    filter='contains'
                    onChange={this.handleLangChange} />
            </div>            
        );
    }
});

Ce dont j'ai besoin, c'est d'obtenir la valeur sélectionnée par utilisateur dans le composant parent. Je reçois cette erreur:

Uncaught TypeError: this.props.onSelectLanguage is not a function

Quelqu'un peut-il m'aider à trouver le problème?

P.S. Le composant enfant crée un menu déroulant à partir d'un fichier json, et j'ai besoin que la liste déroulante affiche les deux éléments du tableau json l'un à côté de l'autre (comme: "aaa, anglais" en premier choix!)

{  
   "languages":[  
      [  
         "aaa",
         "english"
      ],
      [  
         "aab",
         "swedish"
      ],
}
142
Birish

Cela devrait marcher. Lorsque vous renvoyez l'accessoire, vous l'envoyez en tant qu'objet. Vous l'envoyez plutôt en tant que valeur ou vous l'utilisez en tant qu'objet dans le composant parent. Deuxièmement, vous devez formater votre objet Json pour qu'il contienne des paires nom-valeur et utiliser valueField et textField attribut de DropdownList.

Réponse courte

Parent:

<div className="col-sm-9" >
     <SelectLanguage onSelectLanguage={this.handleLanguage}/> 
</div>

Enfant:

handleLangChange = () => {
    var lang = this.dropdown.value;
    this.props.onSelectLanguage(lang);            
}

Détaillé:

EDIT:

Étant donné que React.createClass est obsolète à partir de la v16.0, il est préférable de créer un composant React en développant React.Component. Passer les données du composant enfant au composant parent avec cette syntaxe ressemblera à

Parent

class ParentComponent extends React.Component{
    state: { language: '' }

    handleLanguage = (langValue) => {
        this.setState({language: langValue});
    }

    render() {
         return (
                <div className="col-sm-9" >
                    <SelectLanguage onSelectLanguage={this.handleLanguage}/> 
                </div>
        )
     }
}

Enfant

var json = require("json!../languages.json");
var jsonArray = json.languages;

export class SelectLanguage extends React.Component {
    state = {
            selectedCode: '',
            selectedLanguage: jsonArray[0],
        }

    handleLangChange = () => {
        var lang = this.dropdown.value;
        this.props.onSelectLanguage(lang);            
    }

    render() {
        return (
            <div >
                <DropdownList ref={(ref) => this.dropdown = ref}
                    data={jsonArray} 
                    valueField='lang' textField='lang'
                    caseSensitive={false} 
                    minLength={3}
                    filter='contains'
                    onChange={this.handleLangChange} />
            </div>            
        );
    }
}

Utilisation de la syntaxe createClass utilisée par l'OP dans sa réponse Parent

const ParentComponent = React.createClass({
    getInitialState() {
        return {
            language: '',
        };
    },
    handleLanguage: function(langValue) {
        this.setState({language: langValue});
    },

    render() {
         return (
                <div className="col-sm-9" >
                    <SelectLanguage onSelectLanguage={this.handleLanguage}/> 
                </div>
        );
});

Enfant

var json = require("json!../languages.json");
var jsonArray = json.languages;

export const SelectLanguage = React.createClass({
    getInitialState: function(){
        return{
            selectedCode: '',
            selectedLanguage: jsonArray[0],
        };
    },

    handleLangChange: function () {
        var lang = this.refs.dropdown.value;
        this.props.onSelectLanguage(lang);            
    },

    render() {

        return (
            <div >
                <DropdownList ref='dropdown'
                    data={jsonArray} 
                    valueField='lang' textField='lang'
                    caseSensitive={false} 
                    minLength={3}
                    filter='contains'
                    onChange={this.handleLangChange} />
            </div>            
        );
    }
});

JSON:

{ 
"languages":[ 

    { 
    "code": "aaa", 
    "lang": "english" 
    }, 
    { 
    "code": "aab", 
    "lang": "Swedish" 
    }, 
  ] 
}
176
Shubham Khatri

Pour transmettre des données du composant enfant au composant parent

Dans la composante parentale:

getData(val){
    // do not forget to bind getData in constructor
    console.log(val);
}
render(){
 return(<Child sendData={this.getData}/>);
}

En composante enfant:

demoMethod(){
   this.props.sendData(value);
 }
88
Manisha Tan

J'ai trouvé comment obtenir des données de la composante enfant chez les parents lorsque j'en ai besoin.

Parent:

class ParentComponent extends Component{
  onSubmit(data) {
    let mapPoint = this.getMapPoint();
  }

  render(){
    return (
      <form onSubmit={this.onSubmit.bind(this)}>
        <ChildComponent getCurrentPoint={getMapPoint => {this.getMapPoint = getMapPoint}} />
        <input type="submit" value="Submit" />
      </form>
    )
  }
}

Enfant:

class ChildComponent extends Component{
  constructor(props){
    super(props);

    if (props.getCurrentPoint){
      props.getCurrentPoint(this.getMapPoint.bind(this));
    }
  }

  getMapPoint(){
    return this.Point;
  }
}

Cet exemple montre comment passer d'une fonction du composant enfant au parent et utiliser cette fonction pour obtenir des données à partir de l'enfant.

6
MrDuDuDu

La méthode React.createClass est obsolète dans la nouvelle version de React, vous pouvez le faire très simplement de la manière suivante: créez un composant fonctionnel et un autre composant de classe pour conserver l'état:

Parent:

const ParentComp = () => {
  
  getLanguage = (language) => {
    console.log('Language in Parent Component: ', language);
  }
  
  <ChildComp onGetLanguage={getLanguage}
};

Enfant:

class ChildComp extends React.Component {
    state = {
      selectedLanguage: ''
    }
    
    handleLangChange = e => {
        const language = e.target.value;
        thi.setState({
          selectedLanguage = language;
        });
        this.props.onGetLanguage({language}); 
    }

    render() {
        const json = require("json!../languages.json");
        const jsonArray = json.languages;
        const selectedLanguage = this.state;
        return (
            <div >
                <DropdownList ref='dropdown'
                    data={jsonArray} 
                    value={tselectedLanguage}
                    caseSensitive={false} 
                    minLength={3}
                    filter='contains'
                    onChange={this.handleLangChange} />
            </div>            
        );
    }
};

du composant enfant au composant parent comme ci-dessous

composant parent

class Parent extends React.Component {
   state = { message: "parent message" }
   callbackFunction = (childData) => {
       this.setState({message: childData})
   },
   render() {
        return (
            <div>
                 <Child parentCallback = {this.callbackFunction}/>
                 <p> {this.state.message} </p>
            </div>
        );
   }
}

composant enfant

class Child extends React.Component{
    sendBackData = () => {
         this.props.parentCallback("child message");
    },
    render() { 
       <button onClick={sendBackData}>click me to send back</button>
    }
};

J'espère que ce travail

1
Manoj Rana