Ivo Ivo - 2 months ago 15
React JSX Question

React - send function props to Children

I saw some questions speaking about similar issues but somehow I still do not manage to solve my issue so here I am asking for your kind help. I am pretty new to React and would like to send a function from a Parent to a child and then use it from the Child but somehow when I want to use it it says


Uncaught TypeError: Cannot read property 'props' of undefined"


Edited Code after first answers were helping:

var Menu = React.createClass({
links : [
{key : 1, name : "help", click : this.props.changePageHelp}
],
render : function() {
var menuItem = this.links.map(function(link){
return (
<li key={link.key} className="menu-help menu-link" onClick={link.click}>{link.name}</li>
)
});
return (
<ul>
{menuItem}
</ul>
)
}
});

var Admin = React.createClass ({
_changePageHelp : function() {
console.log('help');
},
render : function () {
return (
<div>
<div id="menu-admin"><Menu changePageHelp={this._changePageHelp.bind(this)} /></div>
</div>
)
}
});

ReactDOM.render(<Admin />, document.getElementById('admin'));

Answer

For performance reasons, you should avoid using bind or arrow functions in JSX props. This is because a copy of the event handling function is created for every instance generated by the map() function. This is explained here: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md

To avoid this you can pull the repeated section into its own component. Here is a demo: http://codepen.io/PiotrBerebecki/pen/EgvjmZ The console.log() call in your parent component receives now the name of the link. You could use it for example in React Router.

var Admin = React.createClass ({
    _changePageHelp : function(name) {
      console.log(name);
    },

    render : function () {
      return (
        <div>
          <div id="menu-admin">
            <Menu changePageHelp={this._changePageHelp} />
          </div>
        </div>
      );
    }
});


var Menu = React.createClass({
  getDefaultProps: function() {
    return {
      links: [
        {key: 1, name: 'help'},
        {key: 2, name: 'about'},
        {key: 3, name: 'contact'}
      ]
    };
  },

  render: function() {
    var menuItem = this.props.links.map((link) => {
      return (
        <MenuItem key={link.key}
                  name={link.name}
                  changePageHelp={this.props.changePageHelp}
                  className="menu-help menu-link" />
      );
    });

    return (
      <ul>
        {menuItem}
      </ul>
    );
  }
});


var MenuItem = React.createClass ({
  handleClick: function() { 
    this.props.changePageHelp(this.props.name);
  },

  render : function () {
    return (
      <li onClick={this.handleClick}>
        Click me to console log in Admin component <b>{this.props.name}</b>
      </li>
    );
  }
});


ReactDOM.render(<Admin />, document.getElementById('admin'));
Comments