Подтвердить что ты не робот

Как передать данные из дочернего компонента в родителя в ReactJS?

Я пытаюсь отправить данные из дочернего компонента в родительский элемент следующим образом:

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

Может ли кто-нибудь помочь мне найти проблему?

P.S. Детский компонент создает выпадающий список из json файла, и мне нужен раскрывающийся список, чтобы показывать оба элемента json-массива рядом друг с другом (например: "aaa, english" в качестве первого выбора!)

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

Ответ 1

Это должно сработать. При отправке оповещения вы отправляете это как объект, скорее отправляете это как значение или, альтернативно, используете его как объект в родительском компоненте. Во-вторых, вам нужно отформатировать свой json-объект, чтобы он содержал пары значений имени, и использовать атрибуты valueField и textField DropdownList

Короткий ответ

Родитель:

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

Ребенок:

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

Подробное:

EDIT:

Учитывая, что React.createClass устарел от версии 16.0, лучше идти вперед и создавать компонент React, расширяя 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" 
    }, 
  ] 
}

Ответ 2

Передача данных из дочернего компонента в родительский компонент

В родительском компоненте:

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

В дочернем компоненте:

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

Ответ 3

Я нашел подход, как получить данные от дочернего компонента у родителей, когда мне это нужно.

родитель:

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

В этом примере показано, как передать функцию из дочернего компонента в родительский и использовать эту функцию для получения данных от дочернего компонента.

Ответ 4

Метод React.createClass объявлен устаревшим в новой версии React. Вы можете сделать это очень просто следующим образом: создать один функциональный компонент и другой компонент класса для поддержания состояния:

Родитель:

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

Ответ 5

от дочернего компонента к родительскому компоненту, как показано ниже

родительский компонент

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

Я надеюсь, что эта работа

Ответ 6

Вы даже можете избежать функции у родителя, обновляющего состояние напрямую

В родительском компоненте:

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

В дочернем компоненте:

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