mirror of
https://github.com/streamich/react-use.git
synced 2026-01-18 14:06:52 +00:00
feat: add useMountedState hook
This commit is contained in:
commit
9081b995ff
@ -101,12 +101,12 @@
|
||||
- [`useTitle`](./docs/useTitle.md) — sets title of the page.
|
||||
- [`usePermission`](./docs/usePermission.md) — query permission status for browser APIs.
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
- [**Lifecycles**](./docs/Lifecycles.md)
|
||||
- [`useEffectOnce`](./docs/useEffectOnce.md) — a modified [`useEffect`](https://reactjs.org/docs/hooks-reference.html#useeffect) hook that only runs once.
|
||||
- [`useEvent`](./docs/useEvent.md) — subscribe to events.
|
||||
- [`useLifecycles`](./docs/useLifecycles.md) — calls `mount` and `unmount` callbacks.
|
||||
- [`useRefMounted`](./docs/useRefMounted.md) — tracks if component is mounted.
|
||||
- [`useMountedState`](./docs/useMountedState.md) and [`useRefMounted`](./docs/useRefMounted.md) — track if component is mounted.
|
||||
- [`usePromise`](./docs/usePromise.md) — resolves promise only while component is mounted.
|
||||
- [`useLogger`](./docs/useLogger.md) — logs in console as component goes through life-cycles.
|
||||
- [`useMount`](./docs/useMount.md) — calls `mount` callbacks.
|
||||
|
||||
25
docs/useMountedState.md
Normal file
25
docs/useMountedState.md
Normal file
@ -0,0 +1,25 @@
|
||||
# `useMountedState`
|
||||
|
||||
Lifecycle hook providing ability to check component's mount state.
|
||||
Gives a function that will return `true` if component mounted and `false` otherwise.
|
||||
|
||||
## Usage
|
||||
|
||||
```jsx
|
||||
import * as React from 'react';
|
||||
import {useMountedState} from 'react-use';
|
||||
|
||||
const Demo = () => {
|
||||
const isMounted = useMountedState();
|
||||
|
||||
React.useEffect(() => {
|
||||
setTimeout(() => {
|
||||
if (isMounted()) {
|
||||
// ...
|
||||
} else {
|
||||
// ...
|
||||
}
|
||||
}, 1000);
|
||||
});
|
||||
};
|
||||
```
|
||||
17
src/__stories__/useMountedState.story.tsx
Normal file
17
src/__stories__/useMountedState.story.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import * as React from 'react';
|
||||
import { useMountedState } from '..';
|
||||
import ShowDocs from './util/ShowDocs';
|
||||
|
||||
const Demo = () => {
|
||||
const isMounted = useMountedState();
|
||||
const [, updateState] = React.useState();
|
||||
|
||||
requestAnimationFrame(updateState);
|
||||
|
||||
return <div>This component is {isMounted() ? 'MOUNTED' : 'NOT MOUNTED'}</div>;
|
||||
};
|
||||
|
||||
storiesOf('Lifecycle|useMountedState', module)
|
||||
.add('Docs', () => <ShowDocs md={require('../../docs/useMountedState.md')} />)
|
||||
.add('Demo', () => <Demo />);
|
||||
28
src/__tests__/useMountedState.test.tsx
Normal file
28
src/__tests__/useMountedState.test.tsx
Normal file
@ -0,0 +1,28 @@
|
||||
import { renderHook } from 'react-hooks-testing-library';
|
||||
import useMountedState from '../useMountedState';
|
||||
|
||||
describe('useMountedState', () => {
|
||||
it('should be defined', () => {
|
||||
expect(useMountedState).toBeDefined();
|
||||
});
|
||||
|
||||
it('should return a function', () => {
|
||||
const hook = renderHook(() => useMountedState(), { initialProps: false });
|
||||
|
||||
expect(typeof hook.result.current).toEqual('function');
|
||||
});
|
||||
|
||||
it('should return true if component is mounted', () => {
|
||||
const hook = renderHook(() => useMountedState(), { initialProps: false });
|
||||
|
||||
expect(hook.result.current()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return false if component is unmounted', () => {
|
||||
const hook = renderHook(() => useMountedState(), { initialProps: false });
|
||||
|
||||
hook.unmount();
|
||||
|
||||
expect(hook.result.current()).toBeFalsy();
|
||||
});
|
||||
});
|
||||
@ -44,6 +44,7 @@ export { default as useMedia } from './useMedia';
|
||||
export { default as useMediaDevices } from './useMediaDevices';
|
||||
export { default as useMotion } from './useMotion';
|
||||
export { default as useMount } from './useMount';
|
||||
export { default as useMountedState } from './useMountedState';
|
||||
export { default as useMouse } from './useMouse';
|
||||
export { default as useMouseHovered } from './useMouseHovered';
|
||||
export { default as useNetwork } from './useNetwork';
|
||||
|
||||
15
src/useMountedState.ts
Normal file
15
src/useMountedState.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
|
||||
export default function useMountedState(): () => boolean {
|
||||
const mountedRef = useRef<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
mountedRef.current = true;
|
||||
|
||||
return () => {
|
||||
mountedRef.current = false;
|
||||
};
|
||||
});
|
||||
|
||||
return () => mountedRef.current;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user