如何在ReactJS中将数据从子组件传递给它的父组件?

时间:2016-07-15 10:37:32

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

14 个答案:

答案 0 :(得分:149)

这应该有效。在发送支持时,您将其作为对象发送,而不是将其作为值发送,或者将其用作父组件中的对象。其次,您需要格式化您的json对象以包含名称值对,并使用valueField的{​​{1}}和textField属性

简答

家长:

DropdownList

儿童:

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

<强>详细说明:

修改

考虑到从V16.0开始不推荐使用React.createClass,最好通过扩展handleLangChange = () => { var lang = this.dropdown.value; this.props.onSelectLanguage(lang); } 来创建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>
        )
     }
}

使用OP在其答案中使用的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

儿童

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

<强> JSON:

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

答案 1 :(得分:80)

将数据从子组件传递到父组件

在父组件中:

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

在子组件中:

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

答案 2 :(得分:19)

考虑到React 功能组件并使用 Hooks 越来越流行,我将举一个简单的示例,说明如何将数据从子组件传递到父组件

在父功能组件中,我们将:

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

然后

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

并将setChildData(其作用类似于类组件中的this.setState)传递给Child

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

首先在儿童部分我们得到了接收道具

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

然后您可以像使用处理程序函数一样以任何方式传递数据

const functionHandler = (data) => {

props.passChildData(data);

}

答案 3 :(得分:6)

我找到了在需要时如何从父组件中获取子组件数据的方法。

父:

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 :(得分:6)

React v16.8+函数组件中,您可以使用useState()创建一个函数状态,该状态使您可以更新父状态,然后将其作为props属性传递给child,然后在child组件内部可以触发父状态功能,以下是有效的代码段:

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>

答案 5 :(得分: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>            
        );
    }
};

答案 6 :(得分:2)

使用回调将数据从子组件传递到父组件

You need to pass from parent to child callback function, and then call it in the child.

父组件:-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);  
  }

答案 7 :(得分:2)

您可以使用useState在ParentComponent中创建状态,并将setIsParentData函数作为prop传递给ChildComponent。

在ChildComponent中,通过prop使用接收的功能更新数据,以将数据发送回ParentComponent。

尤其是当我在ParentComponent中的代码变得太长时,我会使用这种技术,因此,我将从ParentComponent创建子组件。通常,它只会降低1级,使用useContext或redux似乎过分杀伤以便在组件之间共享状态。

ParentComponent.js

import React, { useState } from 'react';
import ChildComponent from './ChildComponent';

export function ParentComponent(){
  const [isParentData, setIsParentData] = useState(True);

  return (
    <p>is this a parent data?: {isParentData}</p>
    <ChildComponent toChild={isParentData} sendToParent={setIsParentData} />
  );
}

ChildComponent.js

import React from 'react';

export function ChildComponent(props){

  return (
    <button onClick={() => {props.sendToParent(False)}}>Update</button>
    <p>The state of isParentData is {props.toChild}</p>
  );
};

答案 8 :(得分:1)

从子组件到父组件如下

父组件

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

我希望这项工作

答案 9 :(得分:1)

这里我想用最简单的方式来解释: 我正在从子组件更新父组件计数器。

父组件(PropsApp.jsx)

import React, { useState } from 'react'
import Child from './Child'

export default function PropsApp(){
   const [counter, setCounter] = useState(0)

   const updateMyCounter = () => {
       setCounter(counter + 1)
   }

   return(
    <>  
        <hr></hr>
        <h1>This is Parent</h1>
        <h2>{counter}</h2>
        <Child updateParent={updateMyCounter} />
    </>
   )
}

子组件(Child.jsx)

export default function Child(props){

return(
    <>  
        <hr></hr>
        <h1>This is Child</h1>
        <button
            onClick={props.updateParent}
        >
            Update Parent Component
        </button>
    </>
   )
}

点击更新父组件,看看神奇 enter image description here

答案 10 :(得分:0)

您甚至可以避免父级函数直接更新状态

在父组件中:

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

在子组件中:

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

答案 11 :(得分:0)

这个想法是向孩子发送一个回调,它将被调用以返回数据

使用函数的完整和最小示例:

应用程序将创建一个子代,该子代将计算随机数并将其直接发送回父代,父代将console.log将结果

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

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

答案 12 :(得分:0)

使用React Hooks

在React中,数据从top-down从父母流向孩子。

父母组件可以将数据传递给孩子,但孩子不能改变父母。 他们可以通过回调将数据传递回父母,但无法直接访问 父母(使用挂钩时也是如此)。

const { useState } = React;

function App() {
  const [count, setCount] = useState(0);
  const increment = () => setCount(count + 1);
  return (
    <div>
      <p>You clicked {count} times</p>
      <Button handleClick={increment} />
    </div>
  );
}

function Button({ handleClick, count }) {
  return <button onClick={handleClick}>Click me</button>;
}

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


<div id="root"></div>

答案 13 :(得分:0)

将数据从子组件传递到父组件的最佳方法

子组件

handleLanguageCode=()=>(langValue) {
  this.props.sendDatatoParent(langValue)
}

父母

this.setState({item:data})} />;