我们可以基于传递给组件的值动态导入钩子吗?
例如。
App.js
<BaseComponent isActive />
BaseComponent.js
if(props.isActive) {
// import useActive (custom Hook)
}
即使道具包含假值,我也不希望导入这些(自定义钩子)文件并增加BaseComponent的大小。
答案 0 :(得分:1)
您可以dynamically import钩子,因为它只是一个函数(使用require
),但是您不应该,因为您不能在条件内部使用钩子。
仅在顶层呼叫挂钩。 不要在循环,条件或嵌套函数中调用挂钩。
如果要有条件地使用钩子,请使用其实现(look for example at skip
option of useQuery
hook from Apollo GraphQL Client)中的条件。
const useActive = (isUsed) => {
if (isUsed) {
// logic
}
}
答案 1 :(得分:-1)
您应该提取useActive
钩子中的逻辑并动态导入它,而不是动态导入该钩子,因为您不应该在循环,条件或嵌套函数中调用钩子。 Rules of Hooks:
假设您的useActive
钩子试图更新文档标题(在现实世界中,您必须考虑使用动态导入的一大段代码)
它可以通过以下方式实现:
// useActive.js
import { useEffect } from "react";
export function useActive() {
useEffect(() => {
document.title = "(Active) Hello World!";
}, []);
}
您尝试在BaseComponent
中使用它:
// BaseComponent.js
function BaseComponent({ isActive }) {
if (isActive) { // <-- call Hooks inside conditions ❌
import("./useActive").then(({ useActive }) => {
useActive();
});
}
return <p>Base</p>;
}
在这里您违反了“请勿在条件内调用Hooks”规则,并且会出现Invalid hook call.
错误。
因此,除了动态导入钩子之外,您还可以提取钩子内部的逻辑并动态导入它:
// updateTitle.js
export function updateTitle() {
document.title = "(Active) Hello World!"
}
然后在挂钩中进行isActive
检查:
// BaseComponent.js
function BaseComponent({ isActive }) {
useEffect(() => {
if (!isActive) return;
import("./updateTitle").then(({ updateTitle }) => {
updateTitle();
});
}, [isActive]);
return <p>Base</p>;
}
它在不违反任何钩子规则的情况下正常工作。
我已附上CodeSandbox,供您试用: