วิธีการส่งผ่านข้อมูลจากองค์ประกอบเด็กไปยังผู้ปกครองใน ReactJS?


211

ฉันกำลังพยายามส่งข้อมูลจากองค์ประกอบลูกไปยังผู้ปกครองดังต่อไปนี้:

const ParentComponent = React.createClass({
    getInitialState() {
        return {
            language: '',
        };
    },
    handleLanguageCode: function(langValue) {
        this.setState({language: langValue});
    },

    render() {
         return (
                <div className="col-sm-9" >
                    <SelectLanguage onSelectLanguage={this.handleLanguage}/> 
                </div>
        );
});

และนี่คือองค์ประกอบย่อย:

export const SelectLanguage = React.createClass({
    getInitialState: function(){
        return{
            selectedCode: '',
            selectedLanguage: '',
        };
    },

    handleLangChange: function (e) {
        var lang = this.state.selectedLanguage;
        var code = this.state.selectedCode;
        this.props.onSelectLanguage({selectedLanguage: lang});   
        this.props.onSelectLanguage({selectedCode: code});           
    },

    render() {
        var json = require("json!../languages.json");
        var jsonArray = json.languages;
        return (
            <div >
                <DropdownList ref='dropdown'
                    data={jsonArray} 
                    value={this.state.selectedLanguage}
                    caseSensitive={false} 
                    minLength={3}
                    filter='contains'
                    onChange={this.handleLangChange} />
            </div>            
        );
    }
});

สิ่งที่ฉันต้องการคือการรับค่าที่เลือกโดยผู้ใช้ในองค์ประกอบหลัก ฉันได้รับข้อผิดพลาดนี้:

Uncaught TypeError: this.props.onSelectLanguage is not a function

ใครสามารถช่วยฉันค้นหาปัญหาได้บ้าง

PS องค์ประกอบลูกกำลังสร้างดรอปดาวน์จากไฟล์ json และฉันต้องการรายการดรอปดาวน์เพื่อแสดงองค์ประกอบทั้งสองของอาร์เรย์ json ถัดจากกันและกัน (เช่น: "aaa, english" เป็นตัวเลือกแรก!)

{  
   "languages":[  
      [  
         "aaa",
         "english"
      ],
      [  
         "aab",
         "swedish"
      ],
}

3
<SelectLanguage onSelectLanguage={this.handleLanguage*Code*}/> พิมพ์ผิด
Yury Tarabanko

@YuryTarabanko ขอบคุณ แต่ยังคงได้รับข้อผิดพลาดเดียวกัน
Birish

@DavinTryon ฉันจะเพิ่มได้อย่างไร ฉันพยายามเช่นนี้ handleLanguageCode: function(langValue) { this.setState({ language: langValue }).bind(this); },แต่มันกลับข้อผิดพลาด:ncaught TypeError: Cannot read property 'bind' of undefined
Birish

2
@DavinTryon createClassตอบกลับวิธีการที่ไม่ตอบสนองอัตโนมัติ
Yury Tarabanko

@OP คุณสามารถสร้างซอแสดงให้เห็นถึงปัญหาได้หรือไม่
Yury Tarabanko

คำตอบ:


259

สิ่งนี้น่าจะใช้ได้ ในขณะที่ส่งเสากลับมาคุณกำลังส่งสิ่งนั้นเป็นวัตถุแทนที่จะส่งว่าเป็นค่าหรือใช้เป็นวัตถุในองค์ประกอบหลัก ประการที่สองคุณต้องจัดรูปแบบวัตถุ json ของคุณเพื่อให้มีคู่ค่าชื่อและการใช้valueFieldและtextFieldคุณลักษณะของDropdownList

คำตอบสั้น ๆ

ต้นทาง:

<div className="col-sm-9">
     <SelectLanguage onSelectLanguage={this.handleLanguage} /> 
</div>

เด็ก:

handleLangChange = () => {
    var lang = this.dropdown.value;
    this.props.onSelectLanguage(lang);            
}

รายละเอียด:

แก้ไข:

พิจารณา React.createClass จะเลิกจาก v16.0 React.Componentเป็นต้นไปมันจะดีกว่าที่จะไปข้างหน้าและสร้างการตอบสนองโดยการขยายตัวแทน การส่งผ่านข้อมูลจากเด็กไปยังองค์ประกอบหลักด้วยไวยากรณ์นี้จะมีลักษณะดังนี้

ผู้ปกครอง

class ParentComponent extends React.Component {

    state = { language: '' }

    handleLanguage = (langValue) => {
        this.setState({language: langValue});
    }

    render() {
         return (
                <div className="col-sm-9">
                    <SelectLanguage onSelectLanguage={this.handleLanguage} /> 
                </div>
        )
     }
}

เด็ก

var json = require("json!../languages.json");
var jsonArray = json.languages;

export class SelectLanguage extends React.Component {
    state = {
            selectedCode: '',
            selectedLanguage: jsonArray[0],
        }

    handleLangChange = () => {
        var lang = this.dropdown.value;
        this.props.onSelectLanguage(lang);            
    }

    render() {
        return (
            <div>
                <DropdownList ref={(ref) => this.dropdown = ref}
                    data={jsonArray} 
                    valueField='lang' textField='lang'
                    caseSensitive={false} 
                    minLength={3}
                    filter='contains'
                    onChange={this.handleLangChange} />
            </div>            
        );
    }
}

ใช้createClassไวยากรณ์ที่ OP ใช้ในคำตอบผู้ปกครองของเขา

const ParentComponent = React.createClass({
    getInitialState() {
        return {
            language: '',
        };
    },

    handleLanguage: function(langValue) {
        this.setState({language: langValue});
    },

    render() {
         return (
                <div className="col-sm-9">
                    <SelectLanguage onSelectLanguage={this.handleLanguage} /> 
                </div>
        );
});

เด็ก

var json = require("json!../languages.json");
var jsonArray = json.languages;

export const SelectLanguage = React.createClass({
    getInitialState: function() {
        return {
            selectedCode: '',
            selectedLanguage: jsonArray[0],
        };
    },

    handleLangChange: function () {
        var lang = this.refs.dropdown.value;
        this.props.onSelectLanguage(lang);            
    },

    render() {

        return (
            <div>
                <DropdownList ref='dropdown'
                    data={jsonArray} 
                    valueField='lang' textField='lang'
                    caseSensitive={false} 
                    minLength={3}
                    filter='contains'
                    onChange={this.handleLangChange} />
            </div>            
        );
    }
});

JSON:

{ 
"languages":[ 

    { 
    "code": "aaa", 
    "lang": "english" 
    }, 
    { 
    "code": "aab", 
    "lang": "Swedish" 
    }, 
  ] 
}

ขอบคุณ Shubham คำตอบของคุณแก้ไขปัญหา แต่ไม่แสดงรายการที่เลือกในรายการแบบเลื่อนลง ว่างเปล่าหลังจากนั้น: /
Birish

@Sarah ในขณะที่สร้าง dropDownList คุณได้กำหนดค่าให้เป็น this.state.selectedLanguage และไม่ได้กำหนดค่าเริ่มต้นเป็นค่าใด ๆ นั่นอาจเป็นปัญหา คุณใช้องค์ประกอบใดของ DropdownList ถ้าฉันรู้บางทีฉันสามารถแก้ไขปัญหานี้ได้
Shubham Khatri

คุณพูดถูก this.state.selectedLanguageดูเหมือนว่าจะเสมอ null: / ฉันใช้ DropDownList จากreact-widgets
Birish

@ Sarah ฉันได้ทำการเปลี่ยนแปลงเล็กน้อยกับรหัสรวมถึงการผูกค่ากับฟังก์ชั่น onChange และการตั้งค่าสถานะเริ่มต้น ลองสิ่งนี้และบอกฉันว่ามันเหมาะกับคุณหรือไม่
Shubham Khatri

ส่งคืนข้อผิดพลาด: Uncaught ReferenceError: value is not defined. ฉันทำการเปลี่ยนแปลงนี้onChange={this.handleLangChange.bind(this, this.value)}และไม่มีข้อผิดพลาดส่งคืน แต่ก็ยังไม่แสดงค่าที่เลือก :(
Birish

108

เพื่อส่งผ่านข้อมูลจากองค์ประกอบลูกไปยังองค์ประกอบหลัก

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

getData(val){
    // do not forget to bind getData in constructor
    console.log(val);
}
render(){
 return(<Child sendData={this.getData}/>);
}

ในองค์ประกอบย่อย:

demoMethod(){
   this.props.sendData(value);
 }

15
อย่าลืมthis.getData = this.getData.bind(this);ในตัวสร้างเนื่องจากคุณอาจได้รับสิ่งนี้ setState ไม่ใช่ฟังก์ชันถ้าคุณต้องการจัดการสถานะใน getData
Miro J.

12

ฉันพบวิธีการรับข้อมูลจากองค์ประกอบลูกในผู้ปกครองเมื่อฉันต้องการ

ต้นทาง:

class ParentComponent extends Component{
  onSubmit(data) {
    let mapPoint = this.getMapPoint();
  }

  render(){
    return (
      <form onSubmit={this.onSubmit.bind(this)}>
        <ChildComponent getCurrentPoint={getMapPoint => {this.getMapPoint = getMapPoint}} />
        <input type="submit" value="Submit" />
      </form>
    )
  }
}

เด็ก:

class ChildComponent extends Component{
  constructor(props){
    super(props);

    if (props.getCurrentPoint){
      props.getCurrentPoint(this.getMapPoint.bind(this));
    }
  }

  getMapPoint(){
    return this.Point;
  }
}

ตัวอย่างนี้แสดงวิธีการส่งผ่านฟังก์ชั่นจากองค์ประกอบเด็กไปยังผู้ปกครองและใช้ฟังก์ชั่นนี้เพื่อรับข้อมูลจากเด็ก


10

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

ในองค์ประกอบฟังก์ชั่นผู้ปกครองเราจะมี:

import React, { useState, useEffect } from "react";

แล้วก็

const [childData, setChildData] = useState("");

และผ่าน setChildData (ซึ่งทำงานคล้ายกับ this.setState ใน Class Components) ให้กับ Child

return( <ChildComponent passChildData={setChildData} /> )

ใน Child Component ก่อนอื่นเราจะได้รับ props

function ChildComponent(props){ return (...) }

จากนั้นคุณสามารถส่งผ่านข้อมูลได้เช่นเดียวกับการใช้ฟังก์ชันตัวจัดการ

const functionHandler = (data) => {

props.passChildData(data);

}

3

วิธี React.createClass เลิกใช้แล้วในเวอร์ชันใหม่ของ React คุณสามารถทำได้ง่ายๆด้วยวิธีดังต่อไปนี้ทำให้ส่วนประกอบที่ใช้งานได้หนึ่งอย่างและส่วนประกอบอีกคลาสหนึ่งเพื่อคงสภาพ:

ต้นทาง:

const ParentComp = () => {
  
  getLanguage = (language) => {
    console.log('Language in Parent Component: ', language);
  }
  
  <ChildComp onGetLanguage={getLanguage}
};

เด็ก:

class ChildComp extends React.Component {
    state = {
      selectedLanguage: ''
    }
    
    handleLangChange = e => {
        const language = e.target.value;
        thi.setState({
          selectedLanguage = language;
        });
        this.props.onGetLanguage({language}); 
    }

    render() {
        const json = require("json!../languages.json");
        const jsonArray = json.languages;
        const selectedLanguage = this.state;
        return (
            <div >
                <DropdownList ref='dropdown'
                    data={jsonArray} 
                    value={tselectedLanguage}
                    caseSensitive={false} 
                    minLength={3}
                    filter='contains'
                    onChange={this.handleLangChange} />
            </div>            
        );
    }
};


3
เพียงแค่ทราบ ... คุณควรอ้างอิง React รุ่นที่เฉพาะเจาะจงแทน "รุ่นใหม่" เพื่อพิสูจน์คำตอบนี้ในอนาคต
steve-o

3

จากองค์ประกอบย่อยไปยังองค์ประกอบหลักดังนี้

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

class Parent extends React.Component {
   state = { message: "parent message" }
   callbackFunction = (childData) => {
       this.setState({message: childData})
   },
   render() {
        return (
            <div>
                 <Child parentCallback = {this.callbackFunction}/>
                 <p> {this.state.message} </p>
            </div>
        );
   }
}

องค์ประกอบลูก

class Child extends React.Component{
    sendBackData = () => {
         this.props.parentCallback("child message");
    },
    render() { 
       <button onClick={sendBackData}>click me to send back</button>
    }
};

ฉันหวังว่างานนี้


2

ในReact v16.8+องค์ประกอบของฟังก์ชั่นคุณสามารถใช้useState()เพื่อสร้างสถานะฟังก์ชั่นที่ช่วยให้คุณอัปเดตสถานะของผู้ปกครองจากนั้นส่งต่อไปยังลูกเป็นคุณลักษณะของอุปกรณ์ประกอบฉากจากนั้นในองค์ประกอบของเด็กที่คุณสามารถเรียกใช้ฟังก์ชั่น :

const { useState , useEffect } = React;

function Timer({ setParentCounter }) {
  const [counter, setCounter] = React.useState(0);

  useEffect(() => {
    let countersystem;
    countersystem = setTimeout(() => setCounter(counter + 1), 1000);

    return () => {
      clearTimeout(countersystem);
    };
  }, [counter]);

  return (
    <div className="App">
      <button
        onClick={() => {
          setParentCounter(counter);
        }}
      >
        Set parent counter value
      </button>
      <hr />
      <div>Child Counter: {counter}</div>
    </div>
  );
}

function App() {
  const [parentCounter, setParentCounter] = useState(0);

  return (
    <div className="App">
      Parent Counter: {parentCounter}
      <hr />
      <Timer setParentCounter={setParentCounter} />
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById('react-root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react-root"></div>


1

คุณสามารถหลีกเลี่ยงฟังก์ชั่นที่ผู้ปกครองอัพเดทสถานะได้โดยตรง

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

render(){
 return(<Child sendData={ v => this.setState({item: v}) } />);
}

ในองค์ประกอบย่อย:

demoMethod(){
   this.props.sendData(value);
}

0

ความคิดคือการส่งโทรกลับไปที่เด็กซึ่งจะถูกเรียกว่าเพื่อให้ข้อมูลกลับ

ตัวอย่างที่สมบูรณ์และน้อยที่สุดโดยใช้ฟังก์ชั่น:

แอพจะสร้างเด็กซึ่งจะคำนวณตัวเลขสุ่มและส่งกลับไปยังผู้ปกครองโดยตรงซึ่งจะconsole.logส่งผลให้

const Child = ({ handleRandom }) => {
  handleRandom(Math.random())

  return <span>child</span>
}
const App = () => <Child handleRandom={(num) => console.log(num)}/>

0

ส่วนประกอบหลัก: -TimeModal

  handleTimeValue = (timeValue) => {
      this.setState({pouringDiff: timeValue});
  }

  <TimeSelection 
        prePourPreHours={prePourPreHours}
        setPourTime={this.setPourTime}
        isPrePour={isPrePour}
        isResident={isResident}
        isMilitaryFormatTime={isMilitaryFormatTime}
        communityDateTime={moment(communityDT).format("MM/DD/YYYY hh:mm A")}
        onSelectPouringTimeDiff={this.handleTimeValue}
     />

หมายเหตุ : - onSelectPouringTimeDiff = {this.handleTimeValue}

ในอุปกรณ์ประกอบฉากการโทรสำหรับองค์ประกอบเด็กเมื่อจำเป็น

 componentDidMount():void{
      // Todo use this as per your scenrio
       this.props.onSelectPouringTimeDiff(pouringDiff);  
  }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.