This should work. While sending the prop back you are sending that as an object rather send that as a value or alternatively use it as an object in the parent component. Secondly you need to format your json object to contain name value pairs and use valueField and textField attribute of DropdownList
Short Answer
Parent:
<div className="col-sm-9">
<SelectLanguage onSelectLanguage={this.handleLanguage} />
</div>
Child:
handleLangChange = () => {
var lang = this.dropdown.value;
this.props.onSelectLanguage(lang);
}
Detailed:
EDIT:
Considering React.createClass is deprecated from v16.0 onwards, It is better to go ahead and create a React Component by extending React.Component. Passing data from child to parent component with this syntax will look like
Parent
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>
)
}
}
Child
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>
);
}
}
Using createClass syntax which the OP used in his answer
Parent
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>
);
});
Child
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"
},
]
}
Answer from Shubham Khatri on Stack Overflowi don't understand how child-to-parent component communication works.
reactjs - React Hook : Send data from child to parent component - Stack Overflow
React - Passing data from child to parent
[SOLVED] React Hooks: how to pass data from Child up to Parent? - Help - PureScript Language Forum
Videos
This should work. While sending the prop back you are sending that as an object rather send that as a value or alternatively use it as an object in the parent component. Secondly you need to format your json object to contain name value pairs and use valueField and textField attribute of DropdownList
Short Answer
Parent:
<div className="col-sm-9">
<SelectLanguage onSelectLanguage={this.handleLanguage} />
</div>
Child:
handleLangChange = () => {
var lang = this.dropdown.value;
this.props.onSelectLanguage(lang);
}
Detailed:
EDIT:
Considering React.createClass is deprecated from v16.0 onwards, It is better to go ahead and create a React Component by extending React.Component. Passing data from child to parent component with this syntax will look like
Parent
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>
)
}
}
Child
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>
);
}
}
Using createClass syntax which the OP used in his answer
Parent
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>
);
});
Child
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"
},
]
}
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);
}
so I'm learning from Maximilian Schwarzmüller's React - The Complete Guide 2024 (incl. React Router & Redux). and on module 5 lecture 15 he is teaching about child-to-parent component communication.
I am watching lecture for 2 weeks now and I simply don't understand how this works. I understand that the child component is communicating up to the main component (app component) but while he was creating his own event-listner I don't get why he uses function and calls in parameter.
I feel dumb not able to understand this. It is frustrating. please help 🙏. explain me in details
A common technique for these situations is to lift the state up to the first common ancestor of all the components that needs to use the state (i.e. the PageComponent in this case) and pass down the state and state-altering functions to the child components as props.
Example
const { useState } = React;
function PageComponent() {
const [count, setCount] = useState(0);
const increment = () => {
setCount(count + 1)
}
return (
<div className="App">
<ChildComponent onClick={increment} count={count} />
<h2>count {count}</h2>
(count should be updated from child)
</div>
);
}
const ChildComponent = ({ onClick, count }) => {
return (
<button onClick={onClick}>
Click me {count}
</button>
)
};
ReactDOM.render(<PageComponent />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
You can create a method in your parent component, pass it to child component and call it from props every time child's state changes, keeping the state in child component.
const EnhancedTable = ({ parentCallback }) => {
const [count, setCount] = useState(0);
return (
<button onClick={() => {
const newValue = count + 1;
setCount(newValue);
parentCallback(newValue);
}}>
Click me {count}
</button>
)
};
class PageComponent extends React.Component {
callback = (count) => {
// do something with value in parent component, like save to state
}
render() {
return (
<div className="App">
<EnhancedTable parentCallback={this.callback} />
<h2>count 0</h2>
(count should be updated from child)
</div>
)
}
}
I’m new to React, but I'm using it for a school project. I'm building a website that uses the Chart.js library to create a line chart. Basically, the actual chart is rendered in a parent component "Graph.js", but the menu/popup used to edit the graph data is stored in a child component "AddMenu.js". In the child component, I've written a function "increment" that increments the specified point of the line chart's dataset when clicked. However, I am now struggling to pass this data from the child component back to the parent, and re-render the parent.
This is my error:
Here is the callback function I've written in the Graph.js parent component:
Here is what my props for the child AddMenu look like:
Here is the increment function I use in the child AddMenu. graphData is an array of seven values imported from Graph.js:
Here is how I call the callback function in the child AddMenu:
I would greatly appreciate any feedback on how to pass back graphData to the Graph parent component. I modify it in the child AddMenu.
If you would like to see my full code for AddMenu and Graph, please let me know and I will attach photos in the comments. Thank you so much!
Suppose the state drive needs to be present in the Parent and the Child. Then you define it in the parent and create a callback function responsible for changing this state setDrive.
In general, the state must be defined at closest common ancestor between the components that use or change this state and this is called Lifting State Up. In your case, something like this (complete demo):
Parent:
const VehicleList = () => {
const classes = useStyles();
const [drive, setDrive] = React.useState(null); // the lifted state
const sendDataToParent = (index) => { // the callback. Use a better name
console.log(index);
setDrive(index);
};
return (
<div className={classes.root}>
{vehicleData.map((vehicle) => (
<div
key={vehicle.name}
style={{
width: "20rem",
border: vehicle.name === drive ? "1px solid red" : null
}}
>
<Vehicle vehicle={vehicle} sendDataToParent={sendDataToParent} />
</div>
))}
</div>
);
};
Child:
const Vehicle = ({ vehicle, sendDataToParent }) => {
const classes = useStyles();
const [showDriveAction, setShowDriveAction] = React.useState(false);
const driveURL = React.useState("");
return (
<Paper className={classes.root} elevation={3}>
<Grid container spacing={2}>
{/* ... */}
<CardActions>
<Button
onClick={() => {
sendDataToParent(vehicle.name);
}} //this is where it needs to be passed
size="small"
color="secondary"
startIcon={<FolderOpenIcon />}
style={{ fontWeight: "bold" }}
>
{/* ... */}
</CardActions>
</Grid>
</Paper>
);
};
Passing data from child to parent in functional components React
const Parent = (props) => {
let onClickFunction = (arg) => alert(arg);
return <Child update={onClickFunction} />
}
const Child({ update }) {
return <button onClick={() => update(1)}> Click </button>;
}
export default Parent;