score:73

Accepted answer

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).

score:15

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

Related Query

More Query from same tag