Metode induk panggilan ReactJS

140

Saya membuat langkah pertama saya di ReactJS dan mencoba memahami komunikasi antara orang tua dan anak-anak. Saya membuat formulir, jadi saya memiliki komponen untuk bidang penataan. Dan juga saya memiliki komponen induk yang mencakup bidang dan memeriksanya. Contoh:

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

Apakah ada cara untuk melakukannya? Dan apakah logika saya baik di "dunia" rejinya? Terima kasih atas waktunya.

KaronatoR
sumber

Jawaban:

154

Untuk melakukan ini, Anda meneruskan panggilan balik sebagai properti ke anak dari orang tua.

Sebagai contoh:

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

Pada contoh di atas, Parentpanggilan Childdengan properti dari valuedan onChange. Sebagai Childgantinya mengikat onChangepawang ke <input />elemen standar dan melewati nilai hingga Parentpanggilan balik jika itu didefinisikan.

Akibatnya Parent's changeHandlermetode ini disebut dengan argumen pertama menjadi nilai string dari <input />lapangan di Child. Hasilnya adalah bahwa Parentstatus dapat diperbarui dengan nilai itu, menyebabkan <span />elemen induk diperbarui dengan nilai baru saat Anda mengetiknya di Childbidang input.

Mike Driver
sumber
15
Saya pikir Anda perlu mengikat fungsi orang tua sebelum meneruskannya kepada anak:<Child value={this.state.value} onChange={this.changeHandler.bind(this)} />
o01
19
@ o01 tidak, Anda tidak melakukannya karena saya menggunakan React.createClassyang otomatis mengikat semua metode komponen. Jika saya menggunakan kelas Bereaksi es6 maka Anda harus mengikatnya (kecuali jika Anda mengikat secara otomatis di konstruktor yang mana banyak orang lakukan hari ini untuk menyiasati ini)
Mike Driver
1
@ MikeDriver saya mengerti. Tidak tahu ini terbatas pada kasus-kasus yang menggunakan kelas ECMAScript 6 (yang saya). Juga tidak menyadari tim Bereaksi merekomendasikan pengikatan otomatis di konstruktor.
O01
1
Saya tidak tahu apakah mereka merekomendasikannya, tapi sepertinya itu hal yang lumrah. Itu lebih masuk akal bagi saya daripada menempatkan ikatan di dalam render thread, alasan .bindmengembalikan fungsi baru, jadi pada dasarnya Anda membuat fungsi baru setiap kali Anda menjalankan render. Ini mungkin baik-baik saja, tetapi jika Anda mengikat dalam konstruktor maka Anda hanya melakukan ini sekali per komponen metode di instantiation daripada setiap render. Ini nit-picking ... tapi secara teknis lebih bagus, kurasa!
Mike Driver
1
@ DavidLy-Gagnon dalam contoh itu mungkin tidak terdefinisi karena saya belum menambahkan isRequired pada propType. Tapi ya Anda bisa melakukan itu atau hanya memeriksa apakah sudah ditentukan atau bukan.
Mike Driver
52

Anda dapat menggunakan metode induk apa pun. Untuk ini, Anda harus mengirim metode ini dari orang tua Anda kepada anak Anda seperti nilai sederhana. Dan Anda dapat menggunakan banyak metode dari orang tua sekaligus. Sebagai contoh:

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

Dan gunakan ke Anak seperti ini (untuk tindakan apa pun atau ke metode anak apa pun):

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
sumber
1
Jawaban yang brilian. Tidak tahu Anda bisa melewatkan metode sebagai alat peraga seperti ini, saya telah menggunakan referensi untuk mencapai ini!
Paul Redmond
1
Saya mendapat panggilan balik untuk dipanggil oleh anak tetapi this.propsdi sana panggilan balik menjadi undefined.
khateeb
Anda harus mengirim panggilan balik ini dari orang tua ke anak (cobalah untuk mengikat panggilan balik ini dengan this)
Vitaliy Andrusishyn
Hai, Valentin Petkov. Selamat datang!
Vitaliy Andrusishyn
39

2019 Pembaruan dengan reaksi 16+ dan ES6

Posting ini karena React.createClasssudah tidak digunakan lagi dari versi reaksi 16 dan Javascript ES6 yang baru akan memberi Anda lebih banyak manfaat.

Induk

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

}

Anak

import React, {Component} from 'react';

export default class Child extends Component {

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

Anak stateless yang disederhanakan sebagai ES6 konstan

import React from 'react';

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

}
export default Child;
Fangming
sumber
Melihat 4 spasi bukannya 2 di ES6 JS membuat saya sedih: '(
Bataleon
3

Lewati metode dari Parentkomponen propke Childkomponen Anda . yaitu:

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
sumber
2

Menggunakan Function || komponen tanpa kewarganegaraan

Komponen Induk

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

Komponen Anak

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
sumber
1
Untuk menambah nilai pada jawaban Anda, pertimbangkan untuk menambahkan penjelasan singkat tentang apa yang dilakukan kode ini.
Cray
ketika Anda mengklik tombol pada komponen anak maka Panggil ke Komponen Induk berfungsi melalui alat peraga.
Omkesh Sajjanwar
1
Bagaimana jika fungsi memiliki parameter? Bagaimana Anda meneruskan parameter ke induk?
alex351
Iya! @ alex351 kita bisa menangani skenario itu. Dalam Komponen Anak -> onClick = {props.handleParentFun ("YoureValue")} Dalam Komponen induk -> handleParentFun = {(nilai) => {console.log (); handleChildFun (nilai); }}
Omkesh Sajjanwar
0

Bereaksi 16+

Komponen Anak

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;

Komponen Induk

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
sumber