如何在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

有人能帮我找到问题吗?

附注:子组件正在从json文件中创建下拉列表,我需要下拉列表来显示json数组的两个元素相邻(如:“aaa,英语”作为首选!)

{
"languages":[
[
"aaa",
"english"
],
[
"aab",
"swedish"
],
}
604065 次浏览

这应该有用。当发送回道具时,您将其作为对象发送,而不是将其作为值发送,或者将其作为父组件中的对象使用。其次,你需要格式化json对象以包含名称值对,并使用DropdownListvalueFieldtextField属性

简短的回答

家长:

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

孩子:

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

详细:

编辑:

考虑到反应。createClass从v16.0起已弃用,最好继续通过扩展React.Component来创建React组件。使用此语法将数据从子组件传递到父组件将如下所示

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

使用OP在回答中使用的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>
);
});

孩子

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

我发现了如何从父母中的子组件中获取数据的方法,当我需要它时。

家长:

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

这个例子展示了如何将函数从子组件传递给父组件,并使用该函数从子组件获取数据。

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

在父组件中:

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

在子组件中:

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

反应。在React的新版本中,createClass方法已经被弃用了,你可以用下面的方法很简单地让一个函数组件和另一个类组件来维护状态:

家长:

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

从子组件到父组件,如下所示

父组件

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

我希望这能起作用

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

在父组件中:

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

在子组件中:

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

其思想是向子程序发送回调,该子程序将被调用以返回数据

一个使用函数的完整且最小的示例:

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

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


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

考虑到React 功能组件和使用钩子现在越来越流行,我将给出一个简单的例子,说明如何将数据从子组件传递给父组件

在父函数组件中,我们将有:

import React, { useState } from "react";

然后

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

和传递setChildData(它们的工作与此类似。setState在类组件)到子

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

在子组件中,我们首先获得接收道具

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

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

const functionHandler = (data) => {


props.passChildData(data);


}

React v16.8+函数组件中,你可以使用useState()创建一个函数状态,让你可以更新父状态,然后将它作为props属性传递给子组件,然后在子组件中你可以触发父状态函数,下面是一个工作代码片段:

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>

使用Callback将数据从子组件传递给父组件

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}

在子组件中,当需要时调用props

 componentDidMount():void{
// Todo use this as per your scenrio
this.props.onSelectPouringTimeDiff(pouringDiff);
}

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

子组件

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

<父sendDatatoParent={数据=>这一点。setState({item: data})} />;

你可以使用useState在ParentComponent中创建状态,并将setIsParentData函数作为道具传递给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>
);
};
在这里,我试图用最简单的方式解释: 我正在从子组件更新父组件计数器

父组件 (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 < / p >

最近我发现了一种很好的方法。

本质上,我只是使用estate,然后设置change作为child的道具,它所需要的“value”。作为参数,并将其放入useState "setVal"boom我得到了state change child >每次都是父母

const Parent = () => {
const [val, setVal] = useState("initial value")
return(
<>
<Child onChange={(value)=> setVal(value)}/>
<div>{val}</div>
</>
)
};


export default Parent;


const Child = (props) => {
return(
<button onClick={() => props.onChange("your value here") }>
)
}
 import { useEffect, useState } from "react";
  

export default function App() {
const data = (data) => {
console.log("data", data);
};
  

const myData = {
name: "hi this is my data"
};
  

return <Form onSubmit={data} myDatasa={myData} />;
}
  

const Form = (props) => {
console.log("myData", props.myDatasa.name);
  

const [choreDesc, setChoreDesc] = useState();
const handleSubmit = (e) => {
e.preventDefault();
props.onSubmit(choreDesc);
};
  

const handlechange = (e) => {
setChoreDesc(e.target.value);
};
  

return (
<form
onSubmit={(e) => {
handleSubmit(e);
}}
>
<label>Chore description:</label>
<br />
<input
name="choreDesc"
type="text"
value={choreDesc}
onChange={handlechange}
/>
<br />
<input type="submit" value="Add Log" />
</form>
);
};
```

在React中,将数据从子组件传递给父组件:

  1. 从接收值的父节点向子节点传递一个函数。
  2. 当子组件中的值发生变化时调用该函数

如。

const Parent = () => {


const handleChange = values => {
alert(JSON.stringify(values) );
//do something with the values
}


return (
<Child handleChange={handleChange} />
);
}


const Child = ({handleChange}) => {
return (
<button onClick={()=> handleChange('values you wish to pass') }}></button>
);
}

注意:从react 16开始,我建议在几乎所有情况下都使用功能组件。

你传递了一个错误的函数给子组件,并且你的父类没有handleLanguage函数。你可以这样传递:<SelectLanguage onSelectLanguage={this.handleLanguageChange}/>。我认为如果一个函数在类中不存在,它将是None。 你的父组件应该是这样的:

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