为啥我无法从 ReactDOM.render() 回调中获取对我的组件的引用?
Posted
技术标签:
【中文标题】为啥我无法从 ReactDOM.render() 回调中获取对我的组件的引用?【英文标题】:Why can I not get a reference to my component from the ReactDOM.render() callback?为什么我无法从 ReactDOM.render() 回调中获取对我的组件的引用? 【发布时间】:2017-04-22 07:58:51 【问题描述】:我有以下代码:
const priceCalculator = ReactDOM.render(<PriceCalculator />, reactHolder);
我需要稍后在我的代码中使用priceCalculator
,但 ESLint 抱怨我不应该使用ReactDOM.render()
的返回值。那时我发现您可以将pass a 3rd argument 转为ReactDOM.render()
,这是一个回调。太好了,我想...
ReactDOM.render(<PriceCalculator />, reactHolder, function(priceCalculator)
// do something with priceCalculator
);
但是priceCalculator
是未定义的。在调试器中,我暂停了异常,发现this
在我在这个函数中时被设置为我的 React 组件。所以我重写它...
ReactDOM.render(<PriceCalculator />, reactHolder, function()
const priceCalculator = this;
// do something with priceCalculator
);
它仍然未定义。怎么回事?
我正在使用 Webpack 编译 es6 React 代码(使用 babel)。
【问题讨论】:
ReactDOM.render
将给定的组件渲染到给定的 DOM 元素中。我相信回调是在渲染完成时调用的。也许你想要的只是做const priceCalculator = <PriceCalculator />
?
@sdgluck 这就是我首先做的,它工作正常。但是不鼓励这种方式,因为最终 ReactDOM.render 可能不会返回任何东西github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/…
回调似乎在小提琴中正常工作:jsfiddle.net/69z2wepo/64439
@sdgluck 我看错了你的答案......没有注意到你没有使用渲染。我需要引用我的组件的特定实例,因为我将侦听器附加到现有(非反应)DOM 节点。这些监听器需要调用我的组件实例的方法。
示例:jsfiddle.net/2zbxats7/1
【参考方案1】:
在您链接的ESLint docs page 中,它说要使用callback ref:
ReactDOM.render() 当前返回对根 ReactComponent 实例的引用。然而,使用这个返回值是遗留的,应该避免,因为未来版本的 React 在某些情况下可能会异步渲染组件。 如果您需要对根 ReactComponent 实例的引用,首选的解决方案是将 callback ref 附加到根元素。
来源:React Top-Level API documentation
因此,您可以通过 prop 将回调传递给根组件,并通过根节点的 ref
prop 从其 render
方法中引用组件的根节点来调用它。
例如(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)
注意:这种方法很幼稚,因为ReactDOM.render
可能并不总是同步渲染,在这种情况下console.log
语句将打印"undefined"
。 (参见上面的引用:“React 的未来版本在某些情况下可能会异步渲染组件”。)
【讨论】:
我调整了你的小提琴,使其更像我想要达到的目标jsfiddle.net/n92sm5f3/1 它确实有效(太棒了!)但我仍然不明白为什么其他方式不能。我链接到的文档页面也说ReactDOM.render(<App />, document.body, doSomethingWithInst);
应该可以工作。
是的,这令人困惑。也许该功能不再可用并且文档已过时 - 您是否使用较旧的 React v. 进行了测试?无论哪种方式,这是推荐的方法。 :-)以上是关于为啥我无法从 ReactDOM.render() 回调中获取对我的组件的引用?的主要内容,如果未能解决你的问题,请参考以下文章
ReactDOM.render:React 从 16.4.2 升级到 16.5.2 后,无法在未安装的组件上找到节点
ReactDOM.render 与 React 组件渲染区别
ReactDOM.render和ReactDOM.createPortal
第十五篇:ReactDOM.render 是如何串联渲染链路的?(下)