I have the following code:
const priceCalculator = ReactDOM.render(<PriceCalculator />, reactHolder);
I need to use priceCalculator
later in my code but ESLint is complaining that I shouldn't use the return value of ReactDOM.render()
. That's when I discovered that you can pass a 3rd argument to ReactDOM.render()
which is a callback. Great I thought...
ReactDOM.render(<PriceCalculator />, reactHolder, function(priceCalculator) {
// do something with priceCalculator
});
But priceCalculator
is undefined. In the debugger I pause on exceptions and find that this
is set to my React Component when I'm inside this function. So I rewrite it...
ReactDOM.render(<PriceCalculator />, reactHolder, function() {
const priceCalculator = this;
// do something with priceCalculator
});
It's still undefined. What's going on?
I'm using Webpack to compile es6 React code (using babel).
In the ESLint docs page you linked it says to use a callback ref:
ReactDOM.render() currently returns a reference to the root ReactComponent instance. However, using this return value is legacy and should be avoided because future versions of React may render components asynchronously in some cases. If you need a reference to the root ReactComponent instance, the preferred solution is to attach a callback ref to the root element.
So you can pass a callback to the root component via a prop and call this with reference to the component's root node from within its render
method, via the root node's ref
prop.
For example (working fiddle):
class Hello extends React.Component {
render () {
return (
<div ref={(node) => this.props.cb(node)}>
Hello {this.state.name}
</div>
)
}
}
let node
ReactDOM.render(<Hello cb={(n) => node = n} />, ...);
console.log(node)
Note: this approach is naive as ReactDOM.render
may not always render synchronously, in which case the console.log
statement would print "undefined"
. (See the above quote: "future versions of React may render components asynchronously in some cases".)