如何避免在嵌套钩子中重复工作(或保持 common/shared 状态)?
How to avoiding repeating work (or to keep common/shared state) in nested hooks?
在嵌套的钩子中:如何知道它是否已经在当前组件(实例)中被调用并访问任何以前的 computed/saved 值?
最好没有 Component
author/the 钩子用户必须知道这一点并且不必做任何特殊的事情就可以工作。
例子
举例说明问题:
const useNestedHook = () => {
// Some heavy work with the same result for each component instance.
// Is it possible to remember the result of this work when
// this hook is used again in the same component instance?
// So I would like to save a state which all uses of useNestedHook
// could access as long as they are in the same component instance.
}
const useHookA = () => {
useNestedHook();
};
const useHookB = () => {
useNestedHook();
};
const Component = () => {
useHookA();
// Would like to avoid useNestedHook repeating its work since it's
// used in the same component and would have this same result (per definition)
// Preferably without the Component author having to know anything about this.
useHookB();
};
想象的解决方案
类似于“命名”共享状态的东西,无论在哪个挂钩中使用它,都可以访问相同的共享状态(在相同的组件实例中)。每个组件实例像往常一样有自己独立的状态。可能是这样的:
const [state, setState] = useSharedState("stateId", initialValue);
不,那是不可能的。每个 useState()
调用将始终与其他 useState()
调用分开。
组件不能像您的示例那样使用挂钩,但组件作者不一定要关心实现细节。
解决方案取决于用例。
一些细节:
一个状态是由useState()
调用写在代码中的地方定义的(参见explanation),它与实例没有直接关系。 IE。两个 useState()
调用和两个实例是 4 个状态值。
您可以使用 共享状态 例如使用 context,但随后状态也会被所有实例共享,而不仅仅是钩子(你不想要的)。
所以 useNestedHook()
永远是“独立的”,但是如果你可以使用共享状态,并且你只关心 “缓存”,并且可以接受useNestedHook()
被调用了两次(即,如果结果相同,则跳过昂贵的操作),然后您可以使用 useEffect()。 IE。该调用将取决于 值 ,而不是实例而不是挂钩。
一些例子:
1。一个带选项的挂钩
例如如果你的钩子 A
和 B
可以选择计算两个不同的值,它们需要相同的 useNestedHook()
值,你可以创建一个带有选项的钩子,例如:
const useHookAB = ({ A, B }) => {
const expensiveValue = useNestedHook();
if( A ){ /* do what useHookA() was doing */ }
if( B ){ /* do what useHookB() was doing */ }
};
const Component = () => {
useHookAB({ A: true, B: true });
};
我现在无法想象您为什么要这样调用挂钩的另一个原因。
2。 “正常”方式
显而易见的解决方案是:
const useHookA = ( value ) => {
// ...
};
const useHookB = ( value ) => {
// ...
};
const Component = () => {
const value = useNestedHook();
useHookA( value );
useHookB( value );
};
但我可以想象您不能(或不喜欢)那样做的原因。
在嵌套的钩子中:如何知道它是否已经在当前组件(实例)中被调用并访问任何以前的 computed/saved 值?
最好没有 Component
author/the 钩子用户必须知道这一点并且不必做任何特殊的事情就可以工作。
例子
举例说明问题:
const useNestedHook = () => {
// Some heavy work with the same result for each component instance.
// Is it possible to remember the result of this work when
// this hook is used again in the same component instance?
// So I would like to save a state which all uses of useNestedHook
// could access as long as they are in the same component instance.
}
const useHookA = () => {
useNestedHook();
};
const useHookB = () => {
useNestedHook();
};
const Component = () => {
useHookA();
// Would like to avoid useNestedHook repeating its work since it's
// used in the same component and would have this same result (per definition)
// Preferably without the Component author having to know anything about this.
useHookB();
};
想象的解决方案
类似于“命名”共享状态的东西,无论在哪个挂钩中使用它,都可以访问相同的共享状态(在相同的组件实例中)。每个组件实例像往常一样有自己独立的状态。可能是这样的:
const [state, setState] = useSharedState("stateId", initialValue);
不,那是不可能的。每个 useState()
调用将始终与其他 useState()
调用分开。
组件不能像您的示例那样使用挂钩,但组件作者不一定要关心实现细节。
解决方案取决于用例。
一些细节:
一个状态是由useState()
调用写在代码中的地方定义的(参见explanation),它与实例没有直接关系。 IE。两个 useState()
调用和两个实例是 4 个状态值。
您可以使用 共享状态 例如使用 context,但随后状态也会被所有实例共享,而不仅仅是钩子(你不想要的)。
所以 useNestedHook()
永远是“独立的”,但是如果你可以使用共享状态,并且你只关心 “缓存”,并且可以接受useNestedHook()
被调用了两次(即,如果结果相同,则跳过昂贵的操作),然后您可以使用 useEffect()。 IE。该调用将取决于 值 ,而不是实例而不是挂钩。
一些例子:
1。一个带选项的挂钩
例如如果你的钩子 A
和 B
可以选择计算两个不同的值,它们需要相同的 useNestedHook()
值,你可以创建一个带有选项的钩子,例如:
const useHookAB = ({ A, B }) => {
const expensiveValue = useNestedHook();
if( A ){ /* do what useHookA() was doing */ }
if( B ){ /* do what useHookB() was doing */ }
};
const Component = () => {
useHookAB({ A: true, B: true });
};
我现在无法想象您为什么要这样调用挂钩的另一个原因。
2。 “正常”方式
显而易见的解决方案是:
const useHookA = ( value ) => {
// ...
};
const useHookB = ( value ) => {
// ...
};
const Component = () => {
const value = useNestedHook();
useHookA( value );
useHookB( value );
};
但我可以想象您不能(或不喜欢)那样做的原因。