Lunny
Lunny

Reputation: 852

React Pass function to child component

I want to pass a function to a child component but I'm getting this error.

Invalid value for prop passedFunction on <div> tag.

class Parent extends Component {
    passedFunction(){}
    render() {
      <Child passedFunction={this.passedFunction}/>
    }
}

class Child extends Component {
    render() {
        <div onClick={this.props.passedFunction}></div>
    }
}

Basically what I'm trying to do.

var ReactGridLayout = require('react-grid-layout');

var MyFirstGrid = React.createClass({
passedFunction:function(){}
  render: function () {
    return (
      <ReactGridLayout className="layout" cols={12} rowHeight={30} width={1200}>
        <div key="a" data-grid={{x: 0, y: 0, w: 1, h: 2, static: true}}>a</div>
        <div key="b" data-grid={{x: 1, y: 0, w: 3, h: 2, minW: 2, maxW: 4}}>b</div>
        <div key="c" data-grid={{x: 4, y: 0, w: 1, h: 2}} passedFunction={this.passedFunction}>c</div>
      </ReactGridLayout>
    )
  }
});

It seems it was introduced in React v16. Therefore, what is the correct way to pass a function from parent to child?

Upvotes: 23

Views: 111749

Answers (4)

Rajesh Bhartia
Rajesh Bhartia

Reputation: 758

If you can bind this function like this it will works

class Parent extends Component {
   passedFunction = () => {};
   render() {
       <Child passedFunction={this.passedFunction} />;
   }
}

class Child extends Component {
   render() {
       <div onClick={this.props.passedFunction} />;
   }
}

Upvotes: 4

Benjamin Charais
Benjamin Charais

Reputation: 1368

Instead of having to bind your function in the constructor of the parent Class, you can use an arrow function to define your method so it is lexically bound using an arrow function

class Child extends Component {
    render() {
        <div onClick={this.props.passedFunction}></div>
    }
}

class Parent extends Component {
    passedFunction = () => {}
    render() {
      <Child passedFunction={this.passedFunction}/>
    }
}

To Account for older version support of Javascript:

class Child extends Component {
    render() {
        <div onClick={this.props.passedFunction}></div>
    }
}

class Parent extends Component {
    constructor() {
        this.passedFunction = this.passedFunction.bind(this)
    }

    passedFunction() {}
    render() {
      <Child passedFunction={this.passedFunction}/>
    }
}

Upvotes: 29

Lunny
Lunny

Reputation: 852

I found out what was wrong. It was because of react-grid-layout. I have to pass the rest of the properties to child.

class Child extends Component {
    render() {
        var { passedFunction, ...otherProps } = this.props;
        return (
            <div onClick={passedFunction} {...otherProps}></div>
        );           
    }
}

Upvotes: 0

Ynahmany
Ynahmany

Reputation: 139

You are missing bind on the Child component.

this.props.passedFunction.bind(this)

Upvotes: 8

Related Questions