ReactJS เรียกเมธอดหลัก


142

ฉันกำลังก้าวแรกใน ReactJS และพยายามทำความเข้าใจการสื่อสารระหว่างผู้ปกครองและเด็ก ฉันกำลังสร้างแบบฟอร์มดังนั้นฉันจึงมีองค์ประกอบสำหรับฟิลด์สไตล์ และฉันมีองค์ประกอบหลักที่มีฟิลด์และตรวจสอบด้วย ตัวอย่าง:

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

มีวิธีใดบ้างที่จะทำได้. และตรรกะของฉันดีใน reactjs "โลก" หรือไม่? ขอบคุณที่สละเวลา.

คำตอบ:


44

อัปเดต 2019 พร้อมตอบสนอง 16+ และ ES6

การโพสต์สิ่งนี้เนื่องจากReact.createClassเลิกใช้งานจาก react เวอร์ชัน 16 และ Javascript ES6 ใหม่จะให้คุณประโยชน์มากขึ้น

ผู้ปกครอง

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

}

เด็ก

import React, {Component} from 'react';

export default class Child extends Component {

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

ทำให้เด็กไร้สัญชาติเป็นค่าคงที่ ES6

import React from 'react';

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

}
export default Child;

การเห็นช่องว่าง 4 ช่องแทนที่จะเป็น 2 ใน ES6 JS ทำให้ฉันเศร้า: '(
Bataleon

154

ในการดำเนินการนี้คุณจะส่งการเรียกกลับเป็นคุณสมบัติไปยังลูกจากผู้ปกครอง

ตัวอย่างเช่น:

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

ในตัวอย่างข้างต้นParentเรียกChildกับทรัพย์สินของและvalue ในการกลับมาผูกจัดการให้มีมาตรฐานองค์ประกอบและส่งผ่านค่าขึ้นไป's โทรกลับถ้ามันกำหนดไว้onChangeChildonChange<input />Parent

ด้วยเหตุParentนี้changeHandlerเมธอดจึงถูกเรียกโดยอาร์กิวเมนต์แรกเป็นค่าสตริงจาก<input />ฟิลด์ในไฟล์Child. ผลลัพธ์ก็คือParentสถานะของสามารถอัปเดตด้วยค่านั้นทำให้<span />องค์ประกอบของผู้ปกครองอัปเดตด้วยค่าใหม่ขณะที่คุณพิมพ์ลงในช่องChildป้อนข้อมูลของ


16
ฉันคิดว่าคุณต้องผูกฟังก์ชันพาเรนต์ก่อนที่จะส่งต่อไปยังลูก:<Child value={this.state.value} onChange={this.changeHandler.bind(this)} />
o01

19
@ o01 ไม่คุณไม่ทำเพราะฉันใช้วิธีReact.createClassการเชื่อมโยงส่วนประกอบทั้งหมดโดยอัตโนมัติ ถ้าฉันใช้คลาส React es6 คุณจะต้องผูกมัน (เว้นแต่คุณจะผูกอัตโนมัติในตัวสร้างซึ่งเป็นสิ่งที่ผู้คนจำนวนมากกำลังทำในทุกวันนี้เพื่อหลีกเลี่ยงสิ่งนี้)
Mike Driver

1
@MikeDriver ฉันเห็น ไม่ทราบว่ากรณีนี้ จำกัด เฉพาะกรณีที่ใช้คลาส ECMAScript 6 (ซึ่งฉันเป็น) ยังไม่ทราบว่าทีม React แนะนำให้ทำการผูกอัตโนมัติในตัวสร้าง
o01

1
ฉันไม่รู้ว่าพวกเขาแนะนำหรือเปล่า แต่ดูเหมือนจะเป็นเรื่องธรรมดาที่ฉันเห็น มันสมเหตุสมผลสำหรับฉันมากกว่าการใส่การโยงเข้าไปในเธรดการเรนเดอร์เหตุผลที่.bindส่งคืนฟังก์ชันใหม่ดังนั้นโดยพื้นฐานแล้วคุณกำลังสร้างฟังก์ชันใหม่ทุกครั้งที่คุณเรียกใช้การเรนเดอร์ สิ่งนี้อาจใช้ได้ แต่ถ้าคุณผูกในตัวสร้างคุณจะทำสิ่งนี้เพียงครั้งเดียวต่อวิธีการคอมโพเนนต์ในการสร้างอินสแตนซ์แทนที่จะเป็นทุกการเรนเดอร์ มันเลือกได้ ... แต่ในทางเทคนิคฉันเดาว่าดีกว่า!
Mike Driver

1
@ DavidLy-Gagnon ในตัวอย่างอาจไม่มีการกำหนดเนื่องจากฉันไม่ได้ต่อท้าย isRequired บน propType แต่คุณสามารถทำได้หรือเพียงแค่ตรวจสอบว่ามีการกำหนดไว้หรือไม่แทน
Mike Driver

52

คุณสามารถใช้วิธีการหลักใดก็ได้ สำหรับสิ่งนี้คุณควรส่งวิธีการนี้จากผู้ปกครองไปยังบุตรหลานของคุณเช่นค่าง่ายๆ และคุณสามารถใช้หลายวิธีจากผู้ปกครองในคราวเดียว ตัวอย่างเช่น:

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

และใช้กับเด็กเช่นนี้ (สำหรับการกระทำใด ๆ หรือในวิธีการย่อยใด ๆ ):

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
คำตอบที่ยอดเยี่ยม ไม่มีความคิดที่คุณสามารถส่งต่อวิธีการเป็นอุปกรณ์ประกอบฉากเช่นนี้ได้ฉันใช้ refs เพื่อให้บรรลุสิ่งนี้!
Paul Redmond

1
ผมได้รับการติดต่อกลับที่จะเรียกได้ว่าเป็นเด็ก แต่มีในการเรียกกลับจะกลายเป็นthis.props undefined
khateeb

คุณควรส่งการโทรกลับนี้จากผู้ปกครองไปยังเด็ก (พยายามผูกการโทรกลับนี้ด้วยthis)
Vitaliy Andrusishyn

สวัสดี Valentin Petkov ยินดีต้อนรับ!
Vitaliy Andrusishyn

3

ส่งต่อวิธีการจากParentองค์ประกอบลงเป็นส่วนประกอบpropของคุณ Childกล่าวคือ:

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

การใช้ฟังก์ชัน || องค์ประกอบไร้สัญชาติ

องค์ประกอบหลัก

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

ส่วนประกอบย่อย

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
หากต้องการเพิ่มมูลค่าให้กับคำตอบของคุณให้พิจารณาเพิ่มคำอธิบายสั้น ๆ ว่ารหัสนี้ทำอะไร
Cray

เมื่อคุณคลิกปุ่มในคอมโพเนนต์ลูกจากนั้นฟังก์ชัน Call to Parent Component ผ่านอุปกรณ์ประกอบฉาก
Omkesh Sajjanwar

1
เกิดอะไรขึ้นถ้าฟังก์ชันมีพารามิเตอร์? คุณส่งผ่านพารามิเตอร์ไปยังพาเรนต์ได้อย่างไร?
alex351

ใช่! @ alex351 เราสามารถจัดการกับสถานการณ์นั้นได้ ในองค์ประกอบลูก -> onClick = {props.handleParentFun ("YoureValue")} ในองค์ประกอบหลัก -> handleParentFun = {(value) => {console.log (); handleChildFun (ค่า); }}
Omkesh Sajjanwar

0

ตอบสนอง 16+

ส่วนประกอบย่อย

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;

องค์ประกอบหลัก

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;

ค่อนข้างแน่ใจว่าองค์ประกอบลูกของคุณที่นี่เป็นส่วนประกอบของคลาสไม่สามารถใช้งานได้ฉันยังใหม่กับการตอบสนองเพื่อให้รู้ว่าฉันผิดหรือไม่
Jason
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.