【问题标题】:Can someone explain in the most layman terms possible what unmountComponentAtNode' does?有人可以用最通俗的术语解释 unmountComponentAtNode' 的作用吗?
【发布时间】:2021-01-25 19:00:13
【问题描述】:

我有一个在 React 组件上运行的测试:

describe(`TheDate Component`, () => {
  it('renders without crashing', () => {
    const div = document.createElement('div');
    ReactDOM.render(<TheDate />, div);
    ReactDOM.unmountComponentAtNode(div);
  })
})

我读到我必须使用“unmountComponentAtNode”,老实说我不太了解unmountComponentAtNode() 的官方文档:

从 DOM 中移除已安装的 React 组件并清理其事件处理程序和状态。如果容器中没有安装任何组件,则调用此函数不会执行任何操作。如果组件已卸载,则返回 true;如果没有要卸载的组件,则返回 false。

我是测试和 React 的新手。

【问题讨论】:

  • unmountComponentAtNode 正确 从 DOM 中删除组件(而不是直接删除 DOM 节点,这是不安全的) - 你能更具体地说明你没有做什么吗?不明白?
  • 我想我不明白为什么它是必要的,在这个测试中它正在创建一个
    来放入 TheDate 组件以查看它是否正确呈现。我很困惑为什么您需要在测试运行后删除该组件。
  • @GenevieveKuzak 取消测试的副作用只是一个好习惯。你可能有更多的测试要遵循这个,它们可能会受到这个测试的副作用的影响。开始“干净”的每个测试。
  • 哦……谢谢!

标签: javascript reactjs


【解决方案1】:

一次一行地执行代码的步骤。第一行:

const div = document.createElement('div');

创建一个'div' HTMLElement。 HTML 如下所示:

<div></div>

下一行:

ReactDOM.render(<TheDate />, div);

这会创建一个 React DOM 元素并将 HTML 表示添加到 div。生成的 HTML 看起来像这样:

<div>
  (whatever HTML is created by TheDate)
<div>

最后一行:

ReactDOM.unmountComponentAtNode(div);

删除渲染到 div 中的 TheDate 组件,并清理与 TheDate 组件关联的所有处理程序和 React 状态(如果有)。

HTML 现在又变成了这样:

<div></div>

下面是一个例子,展示了每一步的效果:

const wrapper = document.getElementById('wrapper');
const btnAddDiv = document.getElementById('addDiv');
const btnRender = document.getElementById('render');
const btnUnmount = document.getElementById('unmount');
const pre = document.querySelector('pre');
let container;

btnAddDiv.onclick = () => {
  container = document.createElement('div');
  container.id = 'container';
  wrapper.appendChild(container);
  showDOM();
  btnAddDiv.disabled = true;
  btnRender.disabled = false;
}

btnRender.onclick = () => {
  const content = ReactDOM.render(
    <h5>I have been rendered!</h5>,
    container);
  showDOM();
  btnRender.disabled = true;
  btnUnmount.disabled = false;
}

btnUnmount.onclick = () => {
  ReactDOM.unmountComponentAtNode(container);
  showDOM();
  btnUnmount.disabled = true;
}

function showDOM() {
  pre.innerText = wrapper.innerHTML;
}

showDOM();
#wrapper {
  margin: 0.5rem;
  padding: 0.5rem;
  border: 1px solid blue;
}
pre {
  margin: 0.5rem;
  border: 1px solid black;
}
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>

<button id="addDiv">.createElement('div')</button>
<button id="render" disabled="true">.render(...)</button>
<button id="unmount" disabled="true">.unmountComponentAtNode(...)</button>

<p>Rendered div and children:</p>
<div id="wrapper">
</div>

<p>HTML of div and children:</p>
<pre></pre>

【讨论】:

    【解决方案2】:

    React 组件“安装”在 DOM 元素上(通常是 &lt;div&gt; 或其他一些容器元素)。

    挂载的行为是告诉 React 它必须从哪里开始渲染组件本身。将“挂载点”视为 React 开始生成在视图中绘制组件所需的所有 html 的锚点。

    例如,在您的测试中,您首先生成一个&lt;div&gt; 元素。此时在您的标记中,您有一个空容器:

    <div>
    </div>
    

    然后,您将“日期”组件“挂载”到之前的 &lt;div&gt;,这就是您调用 ReactDOM.render(&lt;TheDate /&gt;, div) 时所做的事情。

    想象一下您的组件“日期”最终呈现如下内容:

    <div> 
      <h1>Today is <b>25th of January, 2021<b></h1> <!-- This is what React renders -->
    </div> 
    

    当您通过调用 ReactDOM.unmountComponentAtNode(div) 卸载组件时,您基本上是在删除从您的标记生成的所有反应,从而再次导致一个空容器:

    <div>
    </div>
    

    这显然是对使用 react 安装/卸载组件时发生的情况的非常简化的解释,但希望它足够“外行术语”。

    【讨论】:

      猜你喜欢
      相关资源
      最近更新 更多
      热门标签