Ad

In React Can Properties Of Grandparents Be Accessed By A Grandchild Without The Parent Passing It Down?

I am currently working on my first React project and I came into an issue with passing data between components. I am using this libraries calendar widget in order to style different days depending on the selected item in a list.

https://github.com/vazco/meteor-universe-react-widgets

I have four interacting components that are within my tree in this structure:

-----A-----
|         |
C         B
|
|
D

I am currently storing the data of a selected item in a list (Component B) from my top level component (Component A). The component I want to pass the data to is Component D. What I want to do is create a state and pass the value to C and then on to D. Unfortunately, C is the calendar component from the library which I cant really manipulate.

As I need the object generated by the selection in B to be accessed by D without being able to manipulate C, Is there a way to pass values over the head of a child component?

Code snippets:

How Component C (calendar) is called in A, while also passing in component D (dayComponent).

<Calendar dayComponent={DayComponent}/>;

The calendar component declaration & import

System.import('{universe:react-widgets}').then(ReactWidgets => {

    Calendar = ReactWidgets.Calendar;
});

The Day component returns styling for the calendar days.

 DayComponent = React.createClass({
  render() {
    var date = this.props.date
      , style = { backgroundColor: date < new Date() && '#F57B7B' }

    return (<div style={style}>
        {this.props.label}
      </div>);
  }
})
Ad

Answer

Not props, no. That's not how React works. React send props in a top-down direction, with parents passing properties to their children. The idea is that a component shouldn't care where it's rendered, or by what, as long as the props set for it are valid.

That being said, there is a facility for "punching a hole" (so to speak) in your component tree, to allow a child component to access data from higher up in the tree: Context

However, Context is generally regarded to be an advanced feature, and only used in very specific situations where another solution juerally regarded to be an advanced feature, and only used in very specific situations where another solution just isn't viable.

From the docs page:

Note: Context is an advanced and experimental feature. The API is likely to change in future releases. Most applications will never need to use context. Especially if you are just getting started with React, you likely do not want to use context. Using context will make your code harder to understand because it makes the data flow less clear. It is similar to using global variables to pass state through your application. If you have to use context, use it sparingly.

The idea is that in your top level component you define what Context properties you want to make available, and then a method to return the Context data:

class TopComponent extends Component {
  childContextTypes: {
    color: React.PropTypes.string
  },
  getChildContext: function() {
    return {color: "purple"};
  },
  ..
}

And then in a child component somewhere down the tree, you tell that component which Context properties you want access to:

class ChildComponent extends Component {
  contextTypes: {
    color: React.PropTypes.string
  },
  ...
}

And then those properties will be accessible via this.context property (this.context.color for instance).

Ad
source: stackoverflow.com
Ad