25

Is there a recommended pattern for passing props to descendant components in React?

Below, I'm passing the prop callback to a child component:

Master = React.createClass({
  render: function() {
    return (
      <div>
        <ListComp items={this.props.items} callback={this.handleClick} />
      </div>
    );
  }
});

ListComp = React.createClass({
  render: function() {

    this.props.items.forEach(function(item) {
      items.push(<ItemView item={item} callback={this.props.callback} />);
    }, this);

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

And then the callback prop gets handed down to the descendant component:

ItemComp = React.createClass({
  render: function() {
    return (
      <li><a onClick={this.handleClick} href="#">Link</a></li>
    );
  },

  handleClick: function(e) {
    e.preventDefault();
    this.props.callback();
  }
});

Is it correct to pass the prop down twice like this or should I be referencing its inheritance somehow?

I see a transferPropsTo method in the docs, and from logging it looks like I could get to callback from the descendant via this.props.__owner__.props but those double-double underscores make me think I shouldn't.

Dmitry Shvedov
  • 3,169
  • 4
  • 39
  • 51
cantera
  • 24,479
  • 25
  • 95
  • 138
  • I see no problems passing the callback twice. It requires a little more typing but it’s explicit and easy to understand. – NVI Feb 13 '14 at 15:19

1 Answers1

24

Yes, this is idiomatic. Think of each component as a function whose arguments are the props – with that perspective, passing around the props explicitly seems a lot more normal. We've found that it makes things more maintainable to have everything be explicit so you can see what all the inputs to a component are and exactly what you're passing.

(A future version of React will probably include a feature called "contexts" which makes it possible to pass things down implicitly, but it will probably make code harder to reason about so I'd still favor explicitness almost all of the time.)

UPDATE (not by original author)

The documentation has finally been added (it was added sometime between summer 2015 and summer 2016, probably with release 0.14):

Official React Context Documentation.

Note that this is also how react-redux simplifies passing of stores through the hierarchy.

Domi
  • 22,151
  • 15
  • 92
  • 122
Sophie Alpert
  • 139,698
  • 36
  • 220
  • 238
  • 3
    Having worked with a moderately-sized Angular JS app, the "context" feature sounds like Angular's scope mechanics and sounds confusing. $scope vs. $rootScope, scope injection... The explicitness of the current version of React (0.8.0) won me over and lets plain old JS scope rule. – Ross Allen Feb 13 '14 at 17:35
  • 2
    @ssorallen We're very conscious of this. Contexts are currently available in master but they're undocumented and subject to change because we want to make sure to keep things clear. Contexts will probably always be at most an optional, advanced feature. – Sophie Alpert Feb 13 '14 at 18:48
  • That's great. I'm sure within the framework it is useful and in some oddball use cases. – Ross Allen Feb 13 '14 at 19:10
  • There's a blog post called "Introduction to Contexts in React" here: https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html - the feature is undocumented so use with caution, but I've found it useful in some specific cases. – Jed Watson Jan 22 '15 at 00:38