React (vite) hmr破坏了应用程序,页面变空白

huangapple go评论58阅读模式
英文:

React (vite) hmr is breaking the app, the page goes blank

问题

我从cra迁移到vite后遇到了这个问题:

当hmr被触发时,或者当我访问另一个页面时(有时候),页面会变空白,然后我收到很多错误:

Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node. 
上述错误发生在<Fragment>组件中:
上述错误发生在<StrictMode>组件中:

另外:

警告:你正在对一个已经传递给createRoot()的容器上调用ReactDOMClient.createRoot()。相反,如果你想要更新它,只需在现有的根上调用root.render()。

然而,我只在main.tsx文件中调用createRoot一次。

我使用的是react-router-dom:版本是**^6.4.2**。

不幸的是,构建后我仍然看到removeChild错误。

在迁移过程中我做错了什么?

英文:

I migrated from cra to vite and now have the this problem:

When hmr is triggered, or when I visit another page (sometimes), the page goes blank and I get many errors:

Uncaught DOMException: Failed to execute &#39;removeChild&#39; on &#39;Node&#39;: The node to be removed is not a child of this node.
The above error occurred in the &lt;Fragment&gt; component:
The above error occurred in the &lt;StrictMode&gt; component:

Also:

Warning: You are calling ReactDOMClient.createRoot() on a container that has already been passed to createRoot() before. Instead, call root.render() on the existing root instead if you want to update it.

However, I call createRoot only once in main.tsx file.

I use react-router-dom: version "^6.4.2".

I see the removeChild error after build too, unfortunately.

What did I wrong during the migration process?

答案1

得分: 1

这似乎是由于应用程序中的最高组件不是'快速刷新'导致的。这里是来自 Vite 文档的一些信息以及一个eslint插件,可以帮助指出代码中的错误。

之前我的应用程序设置如下:

const ContextWrappers = ({ children }) => (
  <SomeContextProvider>{children}</SomeContextProvider>
)

const App = () => (
  <div className="mega-app">
    <ContextWrappers>
      <YourSexyAppCode />
    </ContextWrapper>
  </div>
)

root.render(
  <App />
);

由于这都在一个文件中,没有导出,所以无法重新加载,因此导致重新加载这些文件的任何操作都会产生您所遇到的错误。

将上下文和应用程序移到单独的文件中解决了我的问题。

另外,我也发现刷新有时会影响热模块替换(HMR)的WebSocket连接,所以我在配置中添加了一个静态端口,如这里所述

hmr: { clientPort: 3000 },
origin: 'https://localhost:3000',
英文:

This appears to be down to the highest component in the app not being 'Fast Refreshable'. Here is some info from the vite docs & an eslint plugin to help point out failures in the code.

Previously my app was set up like so:

const ContextWrappers = ({chidlren}) =&gt; (
   &lt;SomeContextProvider&gt;{chidlren}&lt;/SomeContextProvider&gt; 
)

const App = () =&gt; (
   &lt;div className=&quot;mega-app&quot;&gt;
     &lt;ContextWrappers&gt;
         &lt;YourSexyAppCode /&gt;
     &lt;/ContextWrapper&gt;
   &lt;/div&gt;

)

root.render(
  &lt;App /&gt;
);

As this is all in one file, with no export, it couldn't be reloaded, so anything triggering the reload of these files produced the error you are experiencing.

Moving context and app into separate files resolved the issue for me.

Bonus, I also found refreshing sometimes threw off the WebSocket connection for HMR so added a static port to my config, as outlined here:

  hmr: { clientPort: 3000 },
  origin: &#39;https://localhost:3000&#39;,

huangapple
  • 本文由 发表于 2023年5月21日 08:59:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76297888.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定