Método pai de chamada ReactJS


140

Estou dando o primeiro passo no ReactJS e tentando entender a comunicação entre pais e filhos. Como estou criando um formulário, tenho o componente para estilizar campos. E também tenho componente pai que inclui campo e verificá-lo. Exemplo:

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

Há alguma forma de fazer isso. E minha lógica é boa no "mundo" do reactjs? Obrigado pelo seu tempo.

Respostas:


154

Para fazer isso, você passa um retorno de chamada como uma propriedade para o filho do pai.

Por exemplo:

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

No exemplo acima, Parentchama Childcom uma propriedade de valuee onChange. O Childretorno in vincula um onChangemanipulador a um <input />elemento padrão e passa o valor para o Parentretorno de chamada do, se definido.

Como resultado, o Parent's changeHandlermétodo é chamado com o primeiro argumento é o valor da cadeia do <input />campo no Child. O resultado é que o Parentestado do pode ser atualizado com esse valor, fazendo com que o <span />elemento do pai seja atualizado com o novo valor conforme você o digita no Childcampo de entrada do.


15
Acho que você precisa para ligar a função dos pais antes de passá-lo para a criança:<Child value={this.state.value} onChange={this.changeHandler.bind(this)} />
— O01

19
@ o01 não, você não porque eu estou usando React.createClassqual auto vincula todos os métodos de componentes. Se eu estava usando Reagir aulas ES6 então você precisa vinculá-lo (a menos que você estava no construtor de ligação automática que é o que um monte de pessoas estão fazendo estes dias para contornar esta situação)
— Mike Motorista

1
@ MikeDriver eu vejo. Não sabia que isso era limitado a casos que utilizavam classes ECMAScript 6 (que eu sou). Também não sabia que a equipe do React recomenda a ligação automática no construtor.
— o01 4/06/15

1
Não sei se eles recomendam, mas parece ser uma coisa bastante comum. Faz mais sentido para mim do que colocar o bind dentro do thread de renderização, pelo fato de .bindretornar uma nova função, então basicamente você está criando uma nova função toda vez que executa a renderização. Isso provavelmente é bom, mas se você ligar o construtor, estará fazendo isso apenas uma vez por método de componente na instanciação, em vez de em cada renderização. É uma escolha de nit ... mas tecnicamente melhor, eu acho!
— Mike Motorista

1
@ DavidLy-Gagnon bem no exemplo, pode ser indefinido, pois eu não anexei isRequired no propType. Mas sim, você pode fazer isso ou apenas verificar se foi definido ou não.
— Mike Motorista

52

Você pode usar qualquer método pai. Para isso, você deve enviar esses métodos do seu pai para o seu filho como qualquer valor simples. E você pode usar muitos métodos dos pais ao mesmo tempo. Por exemplo:

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 use-o no Child desta forma (para qualquer ação ou método filho):

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
Resposta brilhante. Não faço ideia de que você poderia passar métodos como adereços como este, eu tenho usado refs para conseguir isso!
— 22618 Paul Redmond

1
Eu recebi o retorno de chamada para ser chamado pela criança, mas lá this.propsno retorno de chamada se torna undefined.
— khateeb 5/09

Você deve enviar este callback de pai para filho (tentar vincular esse retorno de chamada com this)
— Vitaliy Andrusishyn

Olá Valentin Petkov. Bem-vinda!
— Vitaliy Andrusishyn

39

Atualização de 2019 com react 16+ e ES6

A publicação desta publicação React.createClassfoi descontinuada da versão de reação 16 e o ​​novo Javascript ES6 oferecerá mais benefícios.

Pai

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

}

Criança

import React, {Component} from 'react';

export default class Child extends Component {

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

Filho apátrida simplificado como constante ES6

import React from 'react';

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

}
export default Child;

Ver 4 espaços em vez de 2 no ES6 JS me deixa triste: '(
— Bataleon 16/01/19

3

Passe o método do Parentcomponente para baixo como um proppara o seu Childcomponente. ou seja:

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

Usando a função || componente sem estado

Componente pai

 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 filho

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
Para agregar valor à sua resposta, considere adicionar uma breve explicação sobre o que esse código faz.
— Cray

quando você clica no botão no componente filho, a função Chamar para o componente pai via adereços.
— Omkesh Sajjanwar

1
E se a função tiver parâmetros? Como você passa os parâmetros para o pai?
— alex351

sim! @ alex351, podemos lidar com esse cenário. No componente filho -> onClick = {props.handleParentFun ("YoureValue")} No componente pai -> handleParentFun = {(value) => {console.log (); handleChildFun (valor); }}
— Omkesh Sajjanwar

0

Reagir 16+

Componente filho

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 pai

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;
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.