【问题标题】:Unexpected behavior when DOM structure is modified and re-rendered in react修改 DOM 结构并在 react 中重新渲染时出现意外行为
【发布时间】:2015-11-23 13:32:25
【问题描述】:

我有以下使用 react 构建的代码。

<div id="wrapper">
    <form onSubmit={this.handleSubmit}>
        <div id="content">
            .....
        </div>          
    </form>               
</div>

在这里,第三方库会定期更新 DIV#content。但是,在提交表单时,我可以用我的代码中的另一个 DIV 包装 DIV#content。提交修改后请在下方找到:

<div id="wrapper">
    <form onSubmit={this.handleSubmit}>
        <div id="contentWrapper">
            <div id="content">
                .....
            </div>
        </div>          
    </form>               
</div>

但是,一旦 DIV#content 被另一个 DIV 包装,第三方库就会停止工作。谁能告诉我为什么在修改 DOM 结构后它会停止更新 DIV#content,尽管 DIV#content 元素仍然可用于库。

注意:React 不会抛出任何关于 DOM 结构更改的错误,只是库停止工作。

[编辑]:这是我使用 react 渲染的方式

render() {
  var returnIt;
  if (useDivOne) returnIt = (<div id='initial'></div>);
  else returnIt = (<div id='modified'></div>);
  return (returnItj);
}

【问题讨论】:

  • 很大程度上取决于其他库在做什么,以及如何包装 div。一种可能性是,您不是包装现有的 DOM 节点,而是创建一个具有相同内容的新节点。如果您的第三方库持有对原始节点的引用,而不是每次都找到它,则它不会引用新的DIV#content
  • 你能添加一个 React 代码吗?
  • @nAz 我已经添加了示例反应代码。谢谢。

标签: javascript html reactjs


【解决方案1】:

当 React 渲染时,它不会重用旧的 DOM 元素。因此,您的库仍然具有对旧 DOM 引用的引用,而不是在重新渲染时重新创建的新 DOM 引用。由于您的库尚未准备好进行响应,因此您可以通过确保传递给库的 dom 元素永远不会重新创建来以一种迂回的方式进行此操作:

componentDidUpdate() {
    // this makes sure yourDiv is ALWAYS visible inside your
    // component
    if(!this.yourDiv.parentNode) {
        this.refs.libContainer.appendChild(this.yourDiv);
    }
}

render() {

    // you will pass a reference to yourDiv to your library and it will
    // refer to that. YourDiv is NEVER re-created so this DOM element
    // lives forever and your library remains happy
    if(!this.yourDiv) {
        this.yourDiv = document.createElement('div');
        this.yourDiv.className = 'specialDiv';
        this.yourDiv.innerHTML = 'hahahaa';
    }
    return <div ref="libContainer"></div>;
    // .... or sometimes return this
    return <div className="wrapper"><div ref="libContainer"></div></div>;
}

并且您将向您的库传递对 .specialDiv 的引用 - 请注意,我们正在完全跳过 react 如何在此处呈现 DOM,并且这种方法仅在解决 react 干扰您的问题时才真正可行'重新尝试完成 - 因此,如果您实现这一点,我建议制作一个新的反应组件作为您的库的包装器,以便使库反应友好的所有“丑陋”都可以包含在 1 个组件中。

【讨论】:

  • 每当 react 重新渲染时,如果它创建了新的 DOM 引用,那么库应该根本无法更新元素。但是,如果我只是在不改变 DOM 结构和重新渲染的情况下操作任何东西,但在通过用新 div 包装修改结构时则不行。谢谢。
猜你喜欢
  • 2014-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-06
  • 1970-01-01
  • 2021-12-03
  • 1970-01-01
相关资源
最近更新 更多