Méthode parente d'appel ReactJS

140

Je fais mon premier pas dans ReactJS et j'essaie de comprendre la communication entre les parents et les enfants. Je crée un formulaire, j'ai donc le composant pour styliser les champs. Et aussi j'ai un composant parent qui inclut le champ et le vérifie. Exemple:

var LoginField = React.createClass({
    render: function() {
        return (
            <MyField icon="user_icon" placeholder="Nickname" />
        );
    },
    check: function () {
        console.log ("aakmslkanslkc");
    }
})

var MyField = React.createClass({
    render: function() {
...
    },
    handleChange: function(event) {
//call parent!
    }
})

Y a-t-il un moyen de le faire. Et ma logique est-elle bonne dans reactjs "world"? Merci pour votre temps.

KaronatoR
la source

Réponses:

154

Pour ce faire, vous transmettez un rappel en tant que propriété à l'enfant du parent.

Par exemple:

var Parent = React.createClass({

    getInitialState: function() {
        return {
            value: 'foo'
        }
    },

    changeHandler: function(value) {
        this.setState({
            value: value
        });
    },

    render: function() {
        return (
            <div>
                <Child value={this.state.value} onChange={this.changeHandler} />
                <span>{this.state.value}</span>
            </div>
        );
    }
});

var Child = React.createClass({
    propTypes: {
        value:      React.PropTypes.string,
        onChange:   React.PropTypes.func
    },
    getDefaultProps: function() {
        return {
            value: ''
        };
    },
    changeHandler: function(e) {
        if (typeof this.props.onChange === 'function') {
            this.props.onChange(e.target.value);
        }
    },
    render: function() {
        return (
            <input type="text" value={this.props.value} onChange={this.changeHandler} />
        );
    }
});

Dans l'exemple ci-dessus, les Parentappels Childavec une propriété de valueet onChange. Le Childin return lie un onChangegestionnaire à un <input />élément standard et transmet la valeur au Parentrappel de s si elle est définie.

En conséquence, la méthode Parents changeHandlerest appelée avec le premier argument étant la valeur de chaîne du <input />champ dans le Child. Le résultat est que l Parent'état peut être mis à jour avec cette valeur, ce qui entraîne la <span />mise à jour de l' élément parent avec la nouvelle valeur au fur et à mesure que vous la saisissez dans le Childchamp de saisie du.

Mike pilote
la source
15
Je pense que vous devez lier la fonction parent avant de la transmettre à l'enfant:<Child value={this.state.value} onChange={this.changeHandler.bind(this)} />
o01
19
@ o01 non vous ne le faites pas parce que j'utilise React.createClassquelle auto lie toutes les méthodes de composants. Si j'utilisais les classes React es6, vous auriez besoin de le lier (à moins que vous n'ayez une liaison automatique dans le constructeur, ce que beaucoup de gens font ces jours-ci pour contourner cela)
Mike Driver
1
@MikeDriver Je vois. Je ne savais pas que cela était limité aux cas utilisant les classes ECMAScript 6 (ce que je suis). Je ne savais pas non plus que l'équipe React recommande la liaison automatique dans le constructeur.
o01
1
Je ne sais pas s'ils le recommandent, mais cela semble être une chose assez courante que je vois. Cela a plus de sens pour moi que de placer la liaison à l'intérieur du thread de rendu, la raison étant de .bindrenvoyer une nouvelle fonction, vous créez donc une nouvelle fonction à chaque fois que vous exécutez le rendu. C'est probablement bien, mais si vous liez dans le constructeur, vous ne le faites qu'une fois par méthode de composant à l'instanciation plutôt qu'à chaque rendu. C'est difficile ... mais techniquement plus agréable je suppose!
Mike Driver le
1
@ DavidLy-Gagnon bien dans l'exemple, il peut être indéfini car je n'ai pas ajouté isRequired sur le propType. Mais oui, vous pouvez le faire ou simplement vérifier si cela a été défini ou non à la place.
Mike Driver
52

Vous pouvez utiliser n'importe quelle méthode parent. Pour cela, vous devez envoyer ces méthodes de votre parent à votre enfant comme n'importe quelle valeur simple. Et vous pouvez utiliser plusieurs méthodes du parent à la fois. Par exemple:

var Parent = React.createClass({
    someMethod: function(value) {
        console.log("value from child", value)
    },
    someMethod2: function(value) {
        console.log("second method used", value)
    },
    render: function() {
      return (<Child someMethod={this.someMethod} someMethod2={this.someMethod2} />);
    }
});

Et utilisez-le dans l'enfant comme ceci (pour toute action ou dans toute méthode enfant):

var Child = React.createClass({
    getInitialState: function() {
      return {
        value: 'bar'
      }
    },
    render: function() {
      return (<input type="text" value={this.state.value} onClick={this.props.someMethod} onChange={this.props.someMethod2} />);
    }
});
Vitaliy Andrusishyn
la source
1
Réponse géniale. Aucune idée que vous pourriez passer des méthodes comme des accessoires comme celui-ci, j'ai utilisé des références pour y parvenir!
Paul Redmond
1
J'ai reçu le rappel à appeler par l'enfant, mais là, this.propsle rappel devient undefined.
khateeb
Vous devriez envoyer ce rappel de parent à enfant (essayez de lier ce rappel avec this)
Vitaliy Andrusishyn
Salut Valentin Petkov. Bienvenue!
Vitaliy Andrusishyn
39

Mise à jour 2019 avec react 16+ et ES6

Publier ceci depuis React.createClassest obsolète depuis la version 16 de react et le nouveau Javascript ES6 vous donnera plus d'avantages.

Parent

import React, {Component} from 'react';
import Child from './Child';
  
export default class Parent extends Component {

  es6Function = (value) => {
    console.log(value)
  }

  simplifiedFunction (value) {
    console.log(value)
  }

  render () {
  return (
    <div>
    <Child
          es6Function = {this.es6Function}
          simplifiedFunction = {this.simplifiedFunction} 
        />
    </div>
    )
  }

}

Enfant

import React, {Component} from 'react';

export default class Child extends Component {

  render () {
  return (
    <div>
    <h1 onClick= { () =>
            this.props.simplifiedFunction(<SomethingThatYouWantToPassIn>)
          }
        > Something</h1>
    </div>
    )
  }
}

Enfant apatride simplifié comme constante ES6

import React from 'react';

const Child = () => {
  return (
    <div>
    <h1 onClick= { () =>
        this.props.es6Function(<SomethingThatYouWantToPassIn>)
      }
      > Something</h1>
    </div>
  )

}
export default Child;
Fangming
la source
Voir 4 espaces au lieu de 2 dans ES6 JS me rend triste: '(
Bataleon
3

Passez la méthode du Parentcomposant vers le bas comme un propà votre Childcomposant. c'est à dire:

export default class Parent extends Component {
  state = {
    word: ''
  }

  handleCall = () => {
    this.setState({ word: 'bar' })
  }

  render() {
    const { word } = this.state
    return <Child handler={this.handleCall} word={word} />
  }
}

const Child = ({ handler, word }) => (
<span onClick={handler}>Foo{word}</span>
)
Jonca33
la source
2

Utilisation de la fonction || composant sans état

Composant parent

 import React from "react";
 import ChildComponent from "./childComponent";

 export default function Parent(){

 const handleParentFun = (value) =>{
   console.log("Call to Parent Component!",value);
 }
 return (<>
           This is Parent Component
           <ChildComponent 
             handleParentFun={(value)=>{
               console.log("your value -->",value);
               handleParentFun(value);
             }}
           />
        </>);
}

Composant enfant

import React from "react";


export default function ChildComponent(props){
  return(
         <> This is Child Component 
          <button onClick={props.handleParentFun("YoureValue")}>
            Call to Parent Component Function
          </button>
         </>
        );
}
Omkesh Sajjanwar
la source
1
Pour ajouter de la valeur à votre réponse, pensez à ajouter une brève explication sur ce que fait ce code.
Cray
lorsque vous cliquez sur le bouton dans le composant enfant, puis la fonction Appel au composant parent via des accessoires.
Omkesh Sajjanwar le
1
Et si la fonction a des paramètres? Comment passez-vous les paramètres au parent?
alex351
Oui! @ alex351 nous pouvons gérer ce scénario. Dans le composant enfant -> onClick = {props.handleParentFun ("YoureValue")} Dans le composant parent -> handleParentFun = {(valeur) => {console.log (); handleChildFun (valeur); }}
Omkesh Sajjanwar le
0

Réagir 16+

Composant enfant

import React from 'react'

class ChildComponent extends React.Component
{
    constructor(props){
        super(props);       
    }

    render()
    {
        return <div>
            <button onClick={()=>this.props.greetChild('child')}>Call parent Component</button>
        </div>
    }
}

export default ChildComponent;

Composant parent

import React from "react";
import ChildComponent from "./childComponent";

class MasterComponent extends React.Component
{
    constructor(props)
    {
        super(props);
        this.state={
            master:'master',
            message:''
        }
        this.greetHandler=this.greetHandler.bind(this);
    }

    greetHandler(childName){
        if(typeof(childName)=='object')
        {
            this.setState({            
                message:`this is ${this.state.master}`
            });
        }
        else
        {
            this.setState({            
                message:`this is ${childName}`
            });
        }

    }

    render()
    {
        return <div>
           <p> {this.state.message}</p>
            <button onClick={this.greetHandler}>Click Me</button>
            <ChildComponent greetChild={this.greetHandler}></ChildComponent>
        </div>
    }
}
export default  MasterComponent;
Sandeep Shekhawat
la source