ReactJS chiama il metodo parent


140

Sto facendo il mio primo passo in ReactJS e sto cercando di capire la comunicazione tra genitori e figli. Sto facendo forma, quindi ho il componente per i campi di stile. E ho anche un componente genitore che include il campo e lo controlla. Esempio:

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!
    }
})

C'è modo di farlo. E la mia logica è buona nel "mondo" di Reajs? Grazie per il tuo tempo.

Risposte:


154

Per fare ciò si passa un callback come proprietà al figlio dal genitore.

Per esempio:

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} />
        );
    }
});

Nell'esempio sopra, Parentchiama Childcon una proprietà di valuee onChange. Il valore Childrestituito associa un onChangegestore a un <input />elemento standard e passa il valore al Parentcallback se definito.

Come risultato il Parent's changeHandlermetodo viene chiamato con il primo argomento è il valore di stringa del <input />campo nel Child. Il risultato è che lo Parentstato di "può essere aggiornato con quel valore, facendo sì che l' <span />elemento del genitore si aggiorni con il nuovo valore mentre lo digiti nel Childcampo di input".


15
Penso che devi vincolare la funzione genitore prima di <Child value={this.state.value} onChange={this.changeHandler.bind(this)} />
passarla

19
@o01 no, perché non sto usando React.createClassquale auto associa tutti i metodi dei componenti. Se stavo usando le classi React es6, allora avresti bisogno di legarlo (a meno che tu non fossi auto-vincolante nel costruttore, che è quello che molte persone stanno facendo in questi giorni per aggirare questo)
Mike Driver

1
@MikeDriver che vedo. Non sapevo che questo fosse limitato ai casi che utilizzavano le classi ECMAScript 6 (che sono). Inoltre, non ero a conoscenza del fatto che il team di React consiglia l'associazione automatica nel costruttore.
o01,

1
Non so se lo consigliano, ma sembra essere una cosa abbastanza comune che vedo. Per me ha più senso che inserire il bind all'interno del thread di rendering, poiché la ragione .bindrestituisce una nuova funzione, quindi in pratica stai creando una nuova funzione ogni volta che esegui il rendering. Questo probabilmente va bene, ma se si esegue il binding nel costruttore, lo si esegue una sola volta per metodo del componente all'istanza anziché ogni rendering. È pignolo ... ma tecnicamente più bello immagino!
Mike Driver,

1
@ DavidLy-Gagnon bene nell'esempio potrebbe non essere definito in quanto non ho aggiunto isRequired sul propType. Ma sì, puoi farlo o semplicemente verificare se è stato definito o no.
Mike Driver,

52

Puoi usare qualsiasi metodo genitore. Per questo dovresti inviare questi metodi dal tuo genitore al tuo bambino come qualsiasi valore semplice. E puoi usare molti metodi dal genitore contemporaneamente. Per esempio:

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} />);
    }
});

E usalo nel Bambino in questo modo (per qualsiasi azione o in qualsiasi metodo figlio):

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} />);
    }
});

1
Risposta brillante. Non ho idea che potresti passare metodi come oggetti di scena come questo, ho usato refs per raggiungere questo obiettivo!
Paul Redmond,

1
Ho ricevuto il callback per essere chiamato dal bambino ma lì this.propsnel callback diventa undefined.
Khateeb,

Dovresti inviare questo callback da genitore a figlio (prova a legare questo callback con this)
Vitaliy Andrusishyn,

Ciao Valentin Petkov. Benvenuto!
Vitaliy Andrusishyn

39

Aggiornamento 2019 con reagente 16+ ed ES6

Pubblicare questo poiché React.createClassè deprecato dalla versione 16 di reagire e il nuovo Javascript ES6 ti darà più vantaggi.

Genitore

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>
    )
  }

}

Bambino

import React, {Component} from 'react';

export default class Child extends Component {

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

Figlio stateless semplificato come costante ES6

import React from 'react';

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

}
export default Child;

Vedere 4 spazi invece di 2 in ES6 JS mi rende triste: '(
Bataleon

3

Passa il metodo dal Parentcomponente in giù come propal tuo Childcomponente. vale a 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>
)

2

Utilizzando la funzione || componente senza stato

Componente principale

 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);
             }}
           />
        </>);
}

Componente figlio

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>
         </>
        );
}

1
Per aggiungere valore alla tua risposta, considera di aggiungere una breve spiegazione su cosa fa questo codice.
Cray,

quando fai clic sul pulsante nel componente figlio, quindi chiama la funzione Componente padre tramite oggetti di scena.
Omkesh Sajjanwar,

1
Cosa succede se la funzione ha parametri? Come si passano i parametri al genitore?
alex351

sì! @ alex351 possiamo gestire quello scenario. Nel componente figlio -> onClick = {props.handleParentFun ("YoureValue")} Nel componente padre -> handleParentFun = {(value) => {console.log (); handleChildFun (valore); }}
Omkesh Sajjanwar il

0

Reagisci 16+

Componente figlio

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;

Componente principale

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;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.