ReactJS çağrı üst yöntemi


140

ReactJS'de ilk adımımı atıyorum ve ebeveyn ile çocuklar arasındaki iletişimi anlamaya çalışıyorum. Form yapıyorum, bu yüzden alanları şekillendirmek için bileşenim var. Ayrıca alan ve kontrol içeren üst bileşen var. Misal:

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

Bunu yapmanın bir yolu var mı? Ve benim mantığım tepki "dünya" iyi mi? Zaman ayırdığınız için teşekkürler.

Yanıtlar:


154

Bunu yapmak için, ebeveyn olarak alt öğeye bir özellik olarak geri çağrı iletirsiniz.

Örneğin:

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

Yukarıdaki örnekte, ve özelliklerine sahip Parentçağrılar . Buna karşılık, bir işleyiciyi standart bir öğeye bağlar ve tanımlanmışsa değeri 'geri aramasına geçirir .ChildvalueonChangeChildonChange<input />Parent

Sonuç olarak Parent' changeHandleryöntemi çağrılır ve ilk argüman, <input />alandaki dize değeri olur Child. Sonuç olarak, Parent'durumu bu değerle güncellenebilir ve üst <span />öğenin Child' giriş alanına yazdığınızda yeni öğeyle güncellenmesine neden olur .


15
Ben ana işlevi çocuğa geçmeden önce bağlamanız gerektiğini düşünüyorum:<Child value={this.state.value} onChange={this.changeHandler.bind(this)} />
o01

19
@ o01 hayır, çünkü React.createClasstüm bileşen yöntemlerini hangi otomatik olarak bağladığımı kullanıyorum . React es6 sınıflarını kullanıyordum, o zaman onu bağlamanız gerekir (yapıcıda otomatik olarak bağlayıcı olmadıkça, bu günlerde birçok insan bu günlerde bunu yapmak için ne yapıyor)
Mike Driver

1
@MikeDriver anlıyorum. Bunun ECMAScript 6 sınıflarını kullanan vakalarla sınırlı olduğunu bilmiyordum (ki ben). Ayrıca React ekibinin yapıcıda otomatik ciltleme önerdiğinin farkında değildi .
o01

1
Tavsiye edip etmediklerini bilmiyorum, ama gördüğüm oldukça yaygın bir şey gibi görünüyor. Bağlamayı render iş parçacığının içine koymaktan daha mantıklı, nedeni .bindyeni bir işlev döndürüyor, bu nedenle temelde render işlemini her çalıştırdığınızda yeni bir işlev oluşturuyorsunuz. Bu muhtemelen iyidir, ancak yapıcıya bağlarsanız, bunu her render yerine bileşen oluşturma yöntemi başına yalnızca bir kez yaparsınız. Nit-picking ... ama teknik olarak daha güzel sanırım!
Mike Driver

1
@ DavidLy-Gagnon iyi örnekte ben propType isRequired eklediğim gibi tanımsız olabilir. Ama evet ya bunu yapabilir ya da bunun tanımlanıp tanımlanmadığını kontrol edebilirsiniz.
Mike Driver

52

Herhangi bir üst yöntemi kullanabilirsiniz. Bunun için bu yöntemleri ebeveyninizden çocuğunuza herhangi bir basit değer gibi göndermeniz gerekir. Ve aynı anda ebeveynin birçok yöntemini kullanabilirsiniz. Örneğin:

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

Ve bunu Çocukta şu şekilde kullanın (herhangi bir eylem veya herhangi bir alt yöntem için):

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
Mükemmel cevap. Böyle bir sahne gibi yöntemleri aşağı aktarabilirsiniz bilmiyorum, bunu başarmak için refs kullanıyorum!
Paul Redmond

1
Çocuk tarafından aranacak geri çağırma var ama orada this.propsgeri arama olur undefined.
khateeb

Bu geri aramayı ebeveynden çocuğa göndermelisiniz (bu geri aramayı ile bağlanmaya çalışın this)
Vitaliy Andrusishyn

Merhaba Valentin Petkov. Hoşgeldiniz!
Vitaliy Andrusishyn

39

Tepki 16+ ve ES6 ile 2019 Güncellemesi

Bunu React.createClassyayınlamak tepki 16 sürümünden kaldırılmıştır ve yeni Javascript ES6 size daha fazla fayda sağlayacaktır.

ebeveyn

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

}

Çocuk

import React, {Component} from 'react';

export default class Child extends Component {

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

ES6 sabiti olarak basitleştirilmiş vatansız çocuk

import React from 'react';

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

}
export default Child;

ES6 JS'de 2 yerine 4 boşluk görmek beni üzüyor: '(
Bataleon

3

Yöntemi Parentbileşenden bileşeninize a propolarak Childbileşeninize aktarın . yani:

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

İşlev Kullanımı || vatansız bileşen

Üst Bileşen

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

Alt Bileşen

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
Cevabınıza değer katmak için bu kodun ne yaptığına dair kısa bir açıklama eklemeyi düşünün.
Cray

alt bileşendeki düğmeyi tıklattığınızda sahne aracıyla Üst Bileşene Çağrı işlevini kullanın.
Omkesh Sajjanwar

1
Fonksiyonun parametreleri varsa ne olur? Parametreleri ebeveyne nasıl iletirsiniz?
alex351

Evet! @ alex351 bu senaryoyu halledebiliriz. Alt Bileşende -> onClick = {props.handleParentFun ("YoureValue")} Üst Bileşende -> handleParentFun = {(value) => {console.log (); handleChildFun (değer); }}
Omkesh Sajjanwar

0

Reaksiyon 16+

Alt Bileşen

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;

Üst Bileşen

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;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.