I'm trying to send data from a child component to it's parent as follow:
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>
);
});
and here is the child component:
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>
);
}
});
What I need is to get the selected value by user in the parent component. I'm getting this error:
Uncaught TypeError: this.props.onSelectLanguage is not a function
Can anyone help me to find the problem?
P.S. The child component is creating a dropdown from a json file, and I need the dropdown list to show both elements of the json array next to each other(like: "aaa,english" as the first choice!)
{
"languages":[
[
"aaa",
"english"
],
[
"aab",
"swedish"
],
}
This question is related to
reactjs
from child component to parent component as below
parent component
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>
);
}
}
child component
class Child extends React.Component{
sendBackData = () => {
this.props.parentCallback("child message");
},
render() {
<button onClick={sendBackData}>click me to send back</button>
}
};
I hope this work
in React v16.8+
function component, you can use useState()
to create a function state that lets you update the parent state, then pass it on to child as a props attribute, then inside the child component you can trigger the parent state function, the following is a working snippet:
const { useState , useEffect } = React;_x000D_
_x000D_
function Timer({ setParentCounter }) {_x000D_
const [counter, setCounter] = React.useState(0);_x000D_
_x000D_
useEffect(() => {_x000D_
let countersystem;_x000D_
countersystem = setTimeout(() => setCounter(counter + 1), 1000);_x000D_
_x000D_
return () => {_x000D_
clearTimeout(countersystem);_x000D_
};_x000D_
}, [counter]);_x000D_
_x000D_
return (_x000D_
<div className="App">_x000D_
<button_x000D_
onClick={() => {_x000D_
setParentCounter(counter);_x000D_
}}_x000D_
>_x000D_
Set parent counter value_x000D_
</button>_x000D_
<hr />_x000D_
<div>Child Counter: {counter}</div>_x000D_
</div>_x000D_
);_x000D_
}_x000D_
_x000D_
function App() {_x000D_
const [parentCounter, setParentCounter] = useState(0);_x000D_
_x000D_
return (_x000D_
<div className="App">_x000D_
Parent Counter: {parentCounter}_x000D_
<hr />_x000D_
<Timer setParentCounter={setParentCounter} />_x000D_
</div>_x000D_
);_x000D_
}_x000D_
_x000D_
ReactDOM.render(<App />, document.getElementById('react-root'));
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>_x000D_
<div id="react-root"></div>
_x000D_
Best way to pass data from child to parent component
child component
handleLanguageCode=()=>(langValue) {
this.props.sendDatatoParent(langValue)
}
Parent
<Parent sendDatatoParent={ data => this.setState({item: data}) } />;
You can create the state in the ParentComponent using useState
and pass down the setIsParentData
function as prop into the ChildComponent.
In the ChildComponent, update the data using the received function through prop to send the data back to ParentComponent.
I use this technique especially when my code in the ParentComponent is getting too long, therefore I will create child components from the ParentComponent. Typically, it will be only 1 level down and using useContext or redux seems overkill in order to share states between components.
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>
);
};
Considering React Function Components and using Hooks are getting more popular these days , I will give a simple example of how to Passing data from child to parent component
in Parent Function Component we will have :
import React, { useState, useEffect } from "react";
then
const [childData, setChildData] = useState("");
and passing setChildData (which do a job similar to this.setState in Class Components) to Child
return( <ChildComponent passChildData={setChildData} /> )
in Child Component first we get the receiving props
function ChildComponent(props){ return (...) }
then you can pass data anyhow like using a handler function
const functionHandler = (data) => {
props.passChildData(data);
}
I found the approach how to get data from child component in parents when i need it.
Parent:
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>
)
}
}
Child:
class ChildComponent extends Component{
constructor(props){
super(props);
if (props.getCurrentPoint){
props.getCurrentPoint(this.getMapPoint.bind(this));
}
}
getMapPoint(){
return this.Point;
}
}
This example showing how to pass function from child component to parent and use this function to get data from child.
Pass data from child to parent Component using Callback
You need to pass from parent to child callback function, and then call it in the child.
Parent Component:-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}
/>
Note:- onSelectPouringTimeDiff={this.handleTimeValue}
In the Child Component call props when required
componentDidMount():void{
// Todo use this as per your scenrio
this.props.onSelectPouringTimeDiff(pouringDiff);
}
The idea is to send a callback to the child which will be called to give the data back
A complete and minimal example using functions:
App will create a Child which will compute a random number and send it back directly to the parent, which will console.log
the result
const Child = ({ handleRandom }) => {
handleRandom(Math.random())
return <span>child</span>
}
const App = () => <Child handleRandom={(num) => console.log(num)}/>
To pass data from child component to parent component
In Parent Component:
getData(val){
// do not forget to bind getData in constructor
console.log(val);
}
render(){
return(<Child sendData={this.getData}/>);
}
In Child Component:
demoMethod(){
this.props.sendData(value);
}
You can even avoid the function at the parent updating the state directly
In Parent Component:
render(){
return(<Child sendData={ v => this.setState({item: v}) } />);
}
In the Child Component:
demoMethod(){
this.props.sendData(value);
}
React.createClass method has been deprecated in the new version of React, you can do it very simply in the following way make one functional component and another class component to maintain state:
Parent:
const ParentComp = () => {_x000D_
_x000D_
getLanguage = (language) => {_x000D_
console.log('Language in Parent Component: ', language);_x000D_
}_x000D_
_x000D_
<ChildComp onGetLanguage={getLanguage}_x000D_
};
_x000D_
Child:
class ChildComp extends React.Component {_x000D_
state = {_x000D_
selectedLanguage: ''_x000D_
}_x000D_
_x000D_
handleLangChange = e => {_x000D_
const language = e.target.value;_x000D_
thi.setState({_x000D_
selectedLanguage = language;_x000D_
});_x000D_
this.props.onGetLanguage({language}); _x000D_
}_x000D_
_x000D_
render() {_x000D_
const json = require("json!../languages.json");_x000D_
const jsonArray = json.languages;_x000D_
const selectedLanguage = this.state;_x000D_
return (_x000D_
<div >_x000D_
<DropdownList ref='dropdown'_x000D_
data={jsonArray} _x000D_
value={tselectedLanguage}_x000D_
caseSensitive={false} _x000D_
minLength={3}_x000D_
filter='contains'_x000D_
onChange={this.handleLangChange} />_x000D_
</div> _x000D_
);_x000D_
}_x000D_
};
_x000D_
Source: Stackoverflow.com