setState导致不变冲突addComponentAsRefTo

setState cause Invariant Violation addComponentAsRefTo

本文关键字:冲突 addComponentAsRefTo setState      更新时间:2023-09-26

我将react-railsFluxxorReact一起使用。只要我停留在同一页面上,我的组件就可以完全发挥作用。

然而,如果我通过点击其他链接来更改页面,并返回到我的组件,当我尝试在其上使用setState时,它会抛出错误:

Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs. This usually means that you're trying to add a ref to a component that doesn't have an owner (that is, was not created inside of another component's `render` method). Try rendering this component inside of a new top-level component which will hold the ref.

我的实际代码可以在这里找到。这里的问题似乎是setState方法。也许我的Chosen组件的refs属性无法重新渲染?可能是Turbolink引起的?

我认为这是Chosen组件实现中的一个问题。

当它被赋予新的道具时,React会重新渲染它,并在页面中放置新的节点。然而,$.fn.chosen已经被实例化,并且它被附加到不再在页面中的DOM节点上。我怀疑,在这一过程中的某个地方,对旧节点和组件的引用被保留了下来,即使在它们被卸载之后也是如此。

我在React中使用select2时也遇到了同样的问题。我发现Ryan Florence的jQuery+React指南非常有用:

我们需要一种方法来停止使用React进行渲染,执行jQuery对话框,然后再次使用React开始渲染。有些人称之为"门户"。您为React打开了一个门户,跳过一些老派的DOM内容,然后继续在另一边进行。

最大的诀窍是什么都不渲染,然后在组件内部调用React.renderComponent。

var Dialog = React.createClass({
  render: function() {
    // don't render anything, this is where we open the portal
    return <div/>;
  },
  componentDidMount: function() {
    var node = this.getDOMNode();    
    // do the old-school stuff
    var dialog = $(node).dialog().data('ui-dialog');
    // start a new React render tree with our node and the children
    // passed in from above, this is the other side of the portal.
    React.renderComponent(<div>{this.props.children}</div>, node):
  }
});

来源https://github.com/ryanflorence/react-training/blob/gh-pages/lessons/05-wrapping-dom-libs.md