diff --git a/packages/shared/src/hooks/index.ts b/packages/shared/src/hooks/index.ts index 686d2442..8ac636a2 100644 --- a/packages/shared/src/hooks/index.ts +++ b/packages/shared/src/hooks/index.ts @@ -11,3 +11,4 @@ export * from './useAppendTo'; export * from './useScrollLock'; export * from './useNextEffect'; export * from './useIsChanged'; +export * from './useStateWithTrailClear'; diff --git a/packages/shared/src/hooks/useStateWithTrailClear.ts b/packages/shared/src/hooks/useStateWithTrailClear.ts new file mode 100644 index 00000000..4b2d5d6e --- /dev/null +++ b/packages/shared/src/hooks/useStateWithTrailClear.ts @@ -0,0 +1,25 @@ +import React, { useEffect, useState } from 'react'; + +/** + * 带后续清理的状态 + * + * 每当设置一个值,下一次 Effect 就会把它重置为 undefined, + * 也就是说会触发 3 次 effect: + * 1. 外部依赖状态更新 + * 2. 依据外部状态更新内部状态 + * 3. 内部状态恢复为 undefined + * + * 类似电子打火机的点火装置,点着了气体之后接下来就与点火器无关且可以关掉了。 + */ +export function useStateWithTrailClear( + visible: T | undefined, +): ReturnType> { + const [state, setState] = useState(); + + useEffect(() => { + state !== undefined && setState(undefined); + }, [state]); + useEffect(() => setState(visible), [visible]); + + return [state, setState]; +}