【问题标题】: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 = &lt;PriceCalculator /&gt;
  • @sdgluck 这就是我首先做的,它工作正常。但是不鼓励这种方式,因为最终 ReactDOM.render 可能不会返回任何东西github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/…
  • 回调似乎在小提琴中正常工作:jsfiddle.net/69z2wepo/64439
  • @sdgluck 我看错了你的答案......没有注意到你没有使用渲染。我需要引用我的组件的特定实例,因为我将侦听器附加到现有(非反应)DOM 节点。这些监听器需要调用我的组件实例的方法。

标签: reactjs webpack ecmascript-6 babeljs react-dom


【解决方案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(&lt;App /&gt;, document.body, doSomethingWithInst); 应该可以工作。
  • 是的,这令人困惑。也许该功能不再可用并且文档已过时 - 您是否使用较旧的 React v. 进行了测试?无论哪种方式,这是推荐的方法。 :-)
猜你喜欢
  • 2020-04-16
  • 2011-05-21
  • 1970-01-01
  • 2012-01-12
  • 1970-01-01
  • 2020-08-11
  • 2021-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多