繁体   English   中英

如何在不破坏 React 的情况下改变 dom

[英]How to mutate the dom without breaking React

我正在使用一个带有返回一堆 HTML 的组件的库。HTML 中的一些没问题,其中一些需要在渲染后更改。

我知道这是不明智的,但是我处于一种似乎有必要使用这种 hacky 方法的情况。

我的问题是在 dom 突变之后,React 似乎崩溃了。 重新呈现不再发生,控制台中也没有错误指示原因。 这显然是由于突变造成的,但我认为必须有某种方法可以在不破坏 React 的情况下做到这一点。 我尝试了各种方法,包括使用 ref 和 useLayoutEffect。

我在这里创建了一个最小的复制品:

https://codesandbox.io/s/busy-sea-mz04cr

您的沙箱中的几件事:

  • 当您按下按钮时, AppMyComponent中仍然会重新渲染,您可以通过在每个组件中添加console.log("XXX has re-rendered")来证明这一点
  • 通过 ref 更新 DOM 不会导致 React 重新渲染
  • 您的自定义挂钩将始终只执行一次(当MyComponent挂载时),因为依赖项永远不会改变
  • 您的 state 更改(按下按钮)仍在触发事件并更新 state 但您通过 ref 更新的 DOM 删除了data变量的呈现

<div id="data">
    <p>Data: {data}</p>
</div>

<div id="data">
   <p>Data: mutation one</p>
</div>

因此,每次按下按钮,您的<MyComponent />都会更新并呈现相同的 static JSX。

这是一个修改后的沙箱,它将data state 变量传递给效果,使其在按钮更改时触发 + 通过 ref 而不是 replaceChild 的 appendChild,因此我们可以看到重新渲染

一些可能有用的事情:

  • 通过 refs 更新 DOM 无疑会导致问题,也许您应该解析从您提到的库返回的 HTML 并使用dangerouslySetInnerHTML呈现它(假设这样做是安全的并且来自受信任的来源,否则它会打开潜在的漏洞)
<div dangerouslySetInnerHTML={{__html: data}} />
function MyComponent() {
  const [data, setData] = useState("");

  const handleButtonPressed = (html) => {
    const fixedHtml = // ... make your changes to the HTML
    setData(fixedHtml);
  };

  return (
    <div>
      <button onClick={handleButtonPressed}>some button</button>
      <p>{data}</p>
    </div>
  );
}
}

希望对您有所帮助,新版本的 React 文档是一个很棒的资源。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM