Meb*_*rem 7 reactjs webpack create-react-app react-hooks
create-react-app
using 自定义了三个react-app-rewired
,都使用了以下包的相同版本:
"react": "^16.12.0",
"react-app-rewired": "^2.1.5",
"react-dom": "^16.12.0",
"react-router-dom": "^5.1.2",
"react-scripts": "3.3.0",
Run Code Online (Sandbox Code Playgroud)
App 1,“主”应用程序是其他两个应用程序的一个非常简单的外壳public/index.html
,看起来像这样:
<body>
<div class="main-app"></div>
<div class="sub-app-1"></div>
<div class="sub-app-2"></div>
<script src="sub-app-1/static/js/bundle.js" async></script>
<script src="sub-app-1/static/js/0.chunk.js" async></script>
<script src="sub-app-1/static/js/main.chunk.js" async></script>
<script src="sub-app-2/static/js/bundle.js" async></script>
<script src="sub-app-2/static/js/0.chunk.js" async></script>
<script src="sub-app-2/static/js/main.chunk.js" async></script>
</body>
Run Code Online (Sandbox Code Playgroud)
这工作得很好,所有三个应用程序都正确呈现。现在需求略有变化sub-app-2
,例如<PictureFrame />
需要将唯一的组件包含在 中sub-app-1
,我在主项目中创建了一个存根组件,如下所示:
const NullPictureFrame = () => {
return <div></div>;
}
export const PictureFrame = (props: Props) => {
const forceUpdate = useForceUpdate();
useEventListener(window, "PictureFrameComponent.Initialized" as string, () => forceUpdate());
const PictureFrame = window.PictureFrameComponent || NullPictureFrame;
return <PictureFrame />
}
Run Code Online (Sandbox Code Playgroud)
我认为钩子的细节并不重要,但它们在以独立方式运行时确实有效。在sub-app-2
做类似这样的东西
window.PictureFrameComponent = () => <PictureFrame />
Run Code Online (Sandbox Code Playgroud)
这在理论上似乎可行,但在实践中我最终遇到以下错误
The above error occurred in the <PictureFrame> component:
in PictureFrame (at src/index.tsx:17)
in Router (at src/index.tsx:16)
in Unknown (at PictureFrames/index.tsx:21)
in PictureFrame (at src/index.tsx:32) <--- in `main-app`
Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/docs/error-boundaries.html to learn more about error boundaries. index.js:1
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/warnings/invalid-hook-call-warning.html for tips about how to debug and fix this problem.
Run Code Online (Sandbox Code Playgroud)
main-app
并且sub-app-2
正在加载两个不同版本的react
,这在使用钩子时会导致问题。
我曾尝试根据此 github 线程中的建议更新我的 webpack 配置,但似乎sub-app-2
找不到react
使用此方法的参考。我的main-app/config-overrides.js
看起来像这样:
config.resolve.alias["react"] = path.resolve(__dirname, "./node_modules/react");
config.resolve.alias["react-dom"] = path.resolve(__dirname, "./node_modules/react-dom");
Run Code Online (Sandbox Code Playgroud)
我sub-app-1/config-overrides.js
看起来像这样:
config.externals = config.externals || {};
config.externals.react = {
root: "React",
commonjs2: "react",
commonjs: "react",
amd: "react"
};
config.externals["react-dom"] = {
root: "ReactDOM",
commonjs2: "react-dom",
commonjs: "react-dom",
amd: "react-dom"
};
Run Code Online (Sandbox Code Playgroud)
这不会导致任何错误,但也sub-app-2
没有被 webpack 初始化为react
/的代码react-dom
无法找到
编辑1:澄清
Window.postMessage
或类似的这种非常松散的耦合。const PictureFrame = window.PictureFrameComponent || NullPictureFrame;
工作正常,团队一直使用到现在,这加强了上面详述的非常丢失依赖项的想法externals
在main-app
以这种方式和加载它们正如React.js 文档中引用的那样,
挂钩本质上是为了访问无类组件中的状态和其他反应功能而构建的。
使用 Hook 时要记住的规则
仅在顶层调用挂钩
仅从 React 函数调用 Hook
从您发布的详细信息来看,我相信您已经考虑到了上述几点。
对于根本原因分析,您可能需要在代码中设置一些调试语句或在控制台上记录消息以调查组件生命周期。
另外,如果您可以按如下方式重建/重新排列应用程序,那就更好了:
公共/index.html
<body>
<div id="root" class="main-app"></div>
<script>
<!-- scrpits can be kept here -->
</script>
</body>
Run Code Online (Sandbox Code Playgroud)
创建另一个组件Main App并在其中包含sub-app-1和sub-app-2。
由于您使用的是"react-dom": "^16.12.0"
and "react-router-dom": "^5.1.2"
,因此您设置路线会更容易。
不能说这真的能解决你的问题,但这是一个很好的做法。
一切顺利。
归档时间: |
|
查看次数: |
1332 次 |
最近记录: |