Reputation: 2733
passing data from child to parent component via callback function but somehow it's not working. what am I doing wrong here? passing data from child to parent component - react - via callback function
https://codepen.io/silentarrowz/pen/GEMQEP?editors=0010
and here's the code
class App extends React.Component{
constructor(props){
super(props);
this.state={
input:'this is the input for now'
}
//this.handleInput=this.handleInput.bind(this);
}
handleInput(x){
this.setState({
input:x
});
alert(this.state.input);
}
render(){
return(
<div>
<h1>Passing props from Child to Parent Component</h1>
<Child getInput={this.handleInput} />
here's the input: {this.state.input}
</div>
);
}
}
class Child extends React.Component{
constructor(){
super();
this.state={
text:''
}
}
passingProps(e){
var newInput=e.target.value;
//alert(newInput);
this.setState({
text:newInput
});
this.props.getInput(this.state.text);
}
render(){
return(
<div>
<input type="text" placeholder="please input a name..." onChange={this.passingProps} />
</div>
)
}
}
ReactDOM.render(
<App/>,
document.getElementById('app')
);
Upvotes: 8
Views: 18740
Reputation: 550
You can create a method in parent that accepts some data and then sets the received data as parent state. Then pass this method to child as props. Now let the method accept child state as input and then let the method set the received child state as parent state.
Upvotes: 1
Reputation: 1885
Two things that you need to correct it:
this.state.input
after
this.setState({input: 'xxx'})
. Here is reason why not it.this.passingProps = this.passingProps.bind(this)
is defined what this
is current scope. when you use this
in component's function, this
need to be bind.Changed codepen
Upvotes: 1
Reputation: 1198
There are a couple of issues.
1) You have to bind passingProps
constructor(){
super();
this.state={
text:''
}
this.passingProps = this.passingProps.bind(this);
}
2) this.setState
is asynchronous, so it's not guaranteed that this.state.text
will be set to the value you want by the time you pass it to this.props.getInput
. You can either do
this.props.getInput(newInput)
or
this.setState({ text: newInput }, () => {
this.props.getInput(this.state.text);
})
to resolve that issue.
Upvotes: 6
Reputation: 404
this
is not automatically bound in your passingProps function. Try arrow function syntax to bind it.
passingProps = e => {
var newInput=e.target.value;
//alert(newInput);
this.setState({
text:newInput
});
this.props.getInput(this.state.text);
}
Upvotes: 1
Reputation: 3238
In your Child
Component, you have written following code:
passingProps(e){
var newInput=e.target.value;
//alert(newInput);
this.setState({
text:newInput
});
this.props.getInput(this.state.text);
}
The issue is due to the asynchronous behaviour of setState function. It means you can not call setState on one line and expect its updates on next line. Use the callback function of setState to call the function of parent component just like this:
passingProps(e){
var newInput=e.target.value;
//alert(newInput);
this.setState({ text: newInput }, () => {
this.props.getInput(this.state.text);
})
}
Same thing is happening in handleInput function of App component.
Upvotes: 1
Reputation: 1227
class App extends React.Component{
constructor(props){
super(props);
this.state={
input:'this is the input for now'
}
this.handleInput=this.handleInput.bind(this);
}
handleInput(event){
let value = event.target.value;
this.setState({
input:value
});
}
render(){
return(
<div>
<h1>{this.state.input}</h1>
<Child getInput={this.handleInput} />
</div>
);
}
}
class Child extends React.Component{
constructor(){
super(props);
}
render(){
return(
<div>
<input type="text" placeholder="please input a name..." onChange={this.props.getInput} />
</div>
)
}
}
ReactDOM.render(
<App/>,
document.getElementById('app')
);
Here is the answer for your question. I hope your proplem is solved.
Upvotes: 2