souldeux
souldeux

Reputation: 3755

Accessing state of children from parent component?

I don't think I fully understand how the Parent/Child relationship works in React. I have two components, Column and Space. When a Column is rendered, it creates some Spaces. I thought that meant that the Column would be the parent to those Spaces, but either I'm wrong or I'm using some part of React.Children.count(this.props.children) incorrectly - it always tells me that any given Column has 0 children.

Simplified models:

var Column = React.createClass({
    getInitialState: function() {
        return {childCount: '', magicNumber: this.props.magicNumber};
    },
    componentDidMount: function() {
        var newCount = React.Children.count(this.props.children);
        this.setState({childCount: newCount});
    },
    render: function() {
        return (
            <div className='Column'>
               {
                   Array.from({ length: this.state.magicNumber }, (x,y) => <Space key={y}/>)
               }  
            </div>

        );
    }
});

var Space = React.createClass({ 
    render: function() {
        return (
            <div className="Space">
              space here
            </div>
        );
    }
});

It seems like no matter where I put React.children.count(this.props.children) in a Column, it tells me there are 0 children. I would expect the Column generated in the example code to have five children, since five Spaces are created within it.

I figured maybe I was trying to count the Children before they were fully loaded, so I tried writing a click handler like this:

//in Column
setChildCount: function () {
    var newCount = React.Children.count(this.props.children);
    this.setState({childCount: newCount});
}

Then adding a button like this in my Column:

...
render: function() {
        return (
            <div className='Column'>
               {
                   Array.from({ length: this.state.magicNumber }, (x,y) => <Space key={y}/>)
               }  
            <button onClick={this.setChildCount} />
            {this.state.childCount}
            </div>
        );

But my childCount is always and forever 0. Can anyone see where I'm going wrong?

Edit: Ultimately, I want to get a count of all children elements who have X attribute in their state set to Y value, but I am clearly a step or three away from that.

Upvotes: 1

Views: 497

Answers (2)

aw04
aw04

Reputation: 11177

You are rendering Space components as part of the Column component. The parent/child relationship captured by this.props.children looks like this:

var Column = React.createClass({
  render: function() {
    <div className="column">
      {this.props.children}
    </div>
  }
});

ReactDOM.render(
  <Column>
    <Space /> //little space children
    <Space />
  </Column>
);

To get at your specific problem, you don't need anything like this.props.children because you have everything right there in your render method.

So the answer to your question is: apply the same logic as when you render them.

Upvotes: 1

LuisPinto
LuisPinto

Reputation: 1687

The Column component doesn't have any children on that code. Childrens are components which are wrapped by the parent component. So imagine:

<Column>
 <Space/>
 <Space/>
<Column/> 

In this case the parent Column has two children Space

On your code:

        <div className='Column'>
           {
               Array.from({ length: this.state.magicNumber }, (x,y) => <Space key={y}/>)
           }  
        </div>

You are creating new components inside a divnot inside the component Column

Upvotes: 1

Related Questions