Reputation: 5738
I'm trying to pass 1 node as a property of another React component like this:
render: function() {
return (
<div>
<div ref='statusCircle'></div>
<Popover trigger={ this.refs.statusCircle }></Popover>
</div>);
);
}
But in the Popover, this.props.trigger is NULL.
Is there anything wrong with my code?
How can I pass a node-ref to another React component as property?
Upvotes: 4
Views: 6831
Reputation: 7668
After typing this I realized it's really not an answer to the original question but instead a follow-up to your request for suggestions in your comment above. If you really don't believe it should stay, I'll delete it but it's too big for a comment, sorry.
You must be using an old version of React, so this may not look right to you at first, but you could track that information using state in that parent component by doing
ref={ function ( element ) {
// at the top of render() put
// var self = this;
self.setState({
circleWidth: element.offsetWidth,
circleHeight: element.offsetHeight
})
}
Assuming those values change over time, you'll want to add an event listener for that change (which can be added inside that ref
setup) and have it run that setState
again when you need it to re-render.
As for <Popover trigger=
you'll want to do something to the effect of:
<Popover trigger={this.state.circleWidth > 999} />
...where 999 is whatever your trigger value would be. If it returns true, then you render Popover. If not, you destroy it. Both situations would be handled inside Popover but will not need to touch that div
Of course, good practice in React is to do that comparison at the top of render()
and place the result into a variable like isTriggered
.
Upvotes: 2
Reputation: 515
You've misunderstood the component lifecycle in React. See here: Link
See this fiddle. https://jsfiddle.net/uzvoruf7/
Open your console, inspect the code for the "Composite" component, and see the lifecycle hooks.
var Popover = React.createClass({
render: function() {
return (<div>This is a pop-over</div>);
}
});
var Composite = React.createClass({
componentDidMount: function() {
console.log(this.refs.statusCircle); //ok, exists.
},
render: function() {
console.log(this.refs.statusCircle); //doesn't exist, sorry.
return (
<div>
<div ref='statusCircle'></div>
<Popover trigger={this.refs.statusCircle}></Popover>
</div>
);
}
});
ReactDOM.render(
<Composite />,
document.getElementById('container')
);
"refs" come alive once the DOM has been rendered.
Therefore, it follows that inside that return statement, the dom has not been rendered yet, hence the reference is null (or all references are null so to speak).
However, inside componentDidMount, you can see that your references are available just as one would expect.
This is a common error: a possible code smell that needs refactoring. Usually (not always), passing down dom-references is indicative of an imperative thought process and is not the React way. I would suggest an improvement but I'm not aware of your use-case.
Upvotes: 7