I have a function that comes from a parent all the way down to a the child of a child in a component hierarchy. Normally this wouldn't be too much of a problem, but I need to receive a parameter from the child. I am currently getting this error message:
Uncaught (in promise) TypeError: this.props.myFunction is not a function.
Here is an example code to what I a doing:
class SomeComponent extends Component{ constructor(props){ super(props); //does whatever stuff this.myFunction = this.myFunction.bind(this); } //(only applicable to raw and normal forms) myFunction(param){ console.log('do something: ', param); } render(){ return (<div><ChildComponent1 myFunction={()=>this.myFunction()}/></div>) } } class ChildComponent1{ render(){ return (<div><ChildComponent2 myFunction={()=>this.props.myFunction()}/></div>) } } class ChildComponent2{ render(){ return (<Button onClick={()=>this.props.myFunction(param)}>SomeButton</Button>) } }
So just to sum it up: I am passing myFunction as a prop from SomeComponent
all the way down to ChildComponent2
, in which I want it called whenever a button is clicked and to pass a parameters from ChildComponent2
.
Thanks!
Passing state as props from parent to child components is a core concept of React. By keeping state in only a few components and passing it to as many children as needed in the form of props, you will be able to write code that is easier to maintain, and you will thank yourself down the road.
I don't see why you would get that error, but you should be doing myFunction={this.myFunction}
and myFunction={this.props.myFunction}
:
class SomeComponent extends Component{ constructor(props){ super(props); //does whatever stuff this.myFunction = this.myFunction.bind(this); } //(only applicable to raw and normal forms) myFunction(param){ console.log('do something: ', param); } render(){ return (<div><ChildComponent1 myFunction={this.myFunction}/></div>) } } class ChildComponent1{ render(){ return (<div><ChildComponent2 myFunction={this.props.myFunction}/></div>) } } class ChildComponent2{ render(){ return (<Button onClick={()=>this.props.myFunction(param)}>SomeButton</Button>) } }
Wrapping the function call inside another (arrow) function is just unnecessary and won't forward the parameter properly (since all your intermediate arrow functions do not accept a parameter).
An alternative and IMO more clean way to do it would be like this:
class SomeComponent extends Component{ myFunction = param => { console.log('do something: ', param); } render(){ return ( <div> <ChildComponent1 onClick={this.myFunction}/> </div>) } } class ChildComponent1{ render(){ return (<div><ChildComponent2 onClick={this.props.onClick}/></div>) } } class ChildComponent2{ render(){ const { onClick } = this.props // destructure return (<Button onClick={()=>onClick(param)}>SomeButton</Button>) } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With