ReactJS'de alt bileşenden üst öğeye veri nasıl aktarılır?


214

Ben aşağıdaki gibi bir alt bileşen onun üst veri veri göndermeye çalışıyorum:

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

ve işte alt bileşen:

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

Ihtiyacım olan üst bileşen kullanıcı tarafından seçilen değeri elde etmektir. Bu hatayı alıyorum:

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

Birisi sorunu bulmama yardım edebilir mi?

PS Çocuk bileşeni bir json dosyasından bir açılır liste oluşturuyor ve json dizisinin her iki unsurunu yan yana göstermek için açılan listeye ihtiyacım var (örneğin: "aaa, ingilizce" ilk seçenek olarak!)

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

3
<SelectLanguage onSelectLanguage={this.handleLanguage*Code*}/> bir yazım hatası.
Yury Tarabanko

@YuryTarabanko Teşekkürler, ama yine de aynı hatayı alıyorum
Birish

@DavinTryon Nasıl eklemeliyim? Ben böyle denedim: handleLanguageCode: function(langValue) { this.setState({ language: langValue }).bind(this); },Ama bir hata döndürür:ncaught TypeError: Cannot read property 'bind' of undefined
Birish

2
@DavinTryon createClassreaksiyona girmeyen metotları özetler.
Yuri Tarabanko

@OP sorunu gösteren bir keman yaratabilir misiniz?
Yuri Tarabanko

Yanıtlar:


260

Bu çalışmalı. Prop geri gönderilirken bunu bir nesne olarak gönderirsiniz, bunu bir değer olarak gönderirsiniz veya alternatif olarak üst bileşende bir nesne olarak kullanırsınız. İkincisi ad değer çiftleri ve kullanımını içerecek biçimde json nesneyi biçimlendirmek gerekir valueFieldve textFieldniteliğiniDropdownList

Kısa cevap

Veli:

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

Çocuk:

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

Detaylı:

DÜZENLE:

React.createClass'ın v16.0'dan itibaren kullanımdan kaldırıldığı düşünüldüğünde, devam etmek ve genişleterek bir Reaksiyon Bileşeni oluşturmak daha iyidir React.Component. Bu sözdizimiyle alt öğeden üst bileşene veri aktarımı aşağıdaki gibi görünecektir

ebeveyn

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

Çocuk

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

Kullanılması createClassOP onun cevabı kullanılan sözdizimi Ana

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

Çocuk

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" 
    }, 
  ] 
}

Teşekkürler Shubham, cevabınız sorunu çözdü, ancak açılan listeden seçilen öğeyi göstermiyor. Bundan sonra boş: /
Birish

@Sarah dropDownList'i oluştururken değerini this.state.selectedLanguage olarak atadınız ve bu herhangi bir değere başlatılmadı. Sorun bu olabilir. Hangi DropdownList bileşenini kullanıyorsunuz. Biliyorum belki sorunu çözmek için bu konuda çalışabilirim.
Shubham Khatri

Haklısın. Her this.state.selectedLanguagezaman boş görünüyor: / Ben DropdownList kullanıyorumreact-widgets
Birish

@Sarah OnChange işlevi ans değerinin ilk durum değeri ayarlamasına bağlanması dahil, kodda küçük bir değişiklik yaptım. Bunu deneyin ve sizin için işe
yarayıp

Bir hata döndürür: Uncaught ReferenceError: value is not defined. Bu değişikliği yaptım: onChange={this.handleLangChange.bind(this, this.value)}ve hiçbir hata döndürülmedi, ancak yine de seçilen değeri göstermiyor :(
Birish

109

Alt bileşenden üst bileşene veri aktarmak için

Üst Bileşende:

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

Alt Bileşende:

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

15
Yapabileceğinizi unutmayın this.getData = this.getData.bind(this);, çünkü bunu alabilirsiniz. SetState, getData'daki durumu değiştirmek istiyorsanız bir işlev değildir.
Miro

12

İhtiyacım olduğunda ebeveynlerde çocuk bileşeninden nasıl veri alacağımı buldum.

Veli:

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

Çocuk:

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

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

  getMapPoint(){
    return this.Point;
  }
}

Alt bileşenden üst öğeye işlevin nasıl aktarılacağını ve alt öğeden veri almak için bu işlevi nasıl kullanıldığını gösteren bu örnek.


10

Tepki Fonksiyonu Bileşenleri ve Hooks kullanımı bu gün daha popüler hale geldiğinde, verileri çocuktan ana bileşene geçirme konusunda basit bir örnek vereceğim

Üst İşlev Bileşeninde aşağıdakilere sahip olacağız:

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

sonra

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

ve setChildData öğesinin (this.setState öğesine benzer bir işi yapan) Child öğesine geçirilmesi

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

Çocuk Bileşeninde önce alıcı desteği alıyoruz

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

veriyi bir işleyici işlevi kullanmak gibi bir şekilde aktarabilirsiniz

const functionHandler = (data) => {

props.passChildData(data);

}

3

React.createClass yöntemi React'in yeni sürümünde kullanımdan kaldırılmıştır, durumu korumak için bir işlevsel bileşen ve başka bir sınıf bileşeni yapmak için bunu çok basit bir şekilde yapabilirsiniz:

Veli:

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

Çocuk:

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
Sadece bir not ... gelecekteki bu cevabı kanıtlamak için "yeni sürüm" yerine özel React sürümüne başvurmalısınız.
steve-o

3

alt bileşenden ana bileşene aşağıdaki gibi

ana bileşen

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

alt bileşen

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

Umarım bu iş


3

içinde React v16.8+fonksiyon bileşeni kullanabilirsiniz useState()ardından, ebeveyn durumunu güncelleştirmek sonra çocuk bileşenlerin içinde Üst devlet fonksiyonunu tetikleyebilir, bir sahne özellik olarak çocuğa geçmek sağlayan bir fonksiyon durumunu oluşturmak için, aşağıdaki bir çalışma snippet'idir :

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

Üst öğedeki işlevi doğrudan durumu güncellemekten bile kaçınabilirsiniz

Üst Bileşende:

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

Alt Bileşende:

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

0

Fikir, çocuğa veriyi geri vermek için çağrılacak bir geri arama göndermektir.

İşlevleri kullanan eksiksiz ve minimal bir örnek:

Uygulama rastgele bir sayı hesaplayacak ve doğrudan ebeveyne geri gönderecek bir Çocuk yaratacaktır console.log.

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

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

0

Üst Bileşen: -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}
     />

Not : - onSelectPouringTimeDiff = {this.handleTimeValue}

Alt Bileşen'de gerektiğinde arama desteği

 componentDidMount():void{
      // Todo use this as per your scenrio
       this.props.onSelectPouringTimeDiff(pouringDiff);  
  }
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.