Skip to content

Commit

Permalink
Added useTitle, useIsOnline hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
aldrinpvincent committed Mar 12, 2022
1 parent 161de6e commit 36082c2
Show file tree
Hide file tree
Showing 16 changed files with 5,755 additions and 5,619 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ docs/node_modules
docs/.docusaurus
docs/build
docs/src/hooks
docs/blog
dist
example
test
test
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ yarn add react-use-custom-hooks
# Usage

```ts
import { useSafeState } from 'react-use-custom-hooks';
import { useDebounce } from 'react-use-custom-hooks';
```

# Demo
# Documentation and demo

https://react-use-custom-hooks.vercel.app/
39 changes: 39 additions & 0 deletions docs/docs/useIsOnline.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# useIsOnline

A hook for detecting network status of the user. This hook will return a boolean value indicating whether the user is online or not. The value will be automatically updated when the user's network status changes.

<pre>{`import {useIsOnline} from 'react-use-custom-hooks';`}</pre>

:::caution
The hook works based on value of `navigator.onLine` property, so this hook returns `true` does not always mean the user connected to the internet, it can also just a connection to some network.

If the browser doesn't support `navigator.onLine`, the hook will return `false/undefined`.

Early versions of Chrome and Safari always reported "true" for navigator.onLine

Desktop Firefox responds to the status of its "Work Offline" mode. If not in that mode, `navigator.onLine` is always true, regardless of the actual network connectivity status. See [ firefox bug](https://bugzilla.mozilla.org/show_bug.cgi?id=654579) for details.

:::

### Usage example

```typescript
const isOnline: boolean = useIsOnline();
```

### Playground

Try disconnecting and then connecting your network and see the value changes.

```jsx live
function IsOnlineExample(props) {
const isOnline = useIsOnline();
return <>User is online: {isOnline.toString()}</>;
}
```

### API

```typescript
export function useIsOnline(): Boolean;
```
8 changes: 8 additions & 0 deletions docs/docs/useSafeState.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# useSafeState

:::caution This hook will be deprecated soon

The warning from react when you set state on unmounted component will be removed from React 18 onwards since there is no actual memory leak in case of promises and the warning is misleading in those scenarios. Also future version of react offer a feature that lets you preserve DOM and state even when the component is not visible, but disconnect its effects. That might not work will with the implementation of this hook.

See detailed discussion here - https://github.com/reactwg/react-18/discussions/82

:::

A memory safe version of react's `useState` hook. In react, on way memory leak occurs when `setState` operation performed on an unmounted component and it happens mostly with asynchronous operation like AJAX calls.

For example, if the user initiated an AJAX call and navigated away from tha page before the call is returned, the component will get unmounted and when the api call is fulfilled, the `setState` will be performed on the unmounted component causing a memory leak.
Expand Down
50 changes: 50 additions & 0 deletions docs/docs/useTitle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# useTitle

A hook to manage title value of document.

<pre>{`import {useTitle} from 'react-use-custom-hooks';`}</pre>

### Usage example

```typescript
useTitle('My title');
```

### Playground

You can pass static value or computed value, state or prop to `useTitle` hook. The title of the document will get's updated whenever the value changes. Also you can restore the previous title if the component using this hook unmounts. Pass `restoreOnUnmount` value `true` in `options` object to configure the behavior.

```jsx live
function TitleExample(props) {
const [title, setTitle] = useState('My Title!');
useTitle(title);
return (
<>
<input
type="text"
value={title}
onChange={e => setTitle(e.target.value)}
/>
</>
);
}
```

### API

```typescript
interface Options {
restoreOnUnmount?: boolean;
}

export function useTitle(
title: string,
options: Options = DEFAULT_OPTIONS
): void;
```

#### Options

| Property | Description | Type | Default |
| ---------------- | ---------------------------------------------- | --------- | ------- |
| restoreOnUnmount | Indicate to restore the title value on unmount | `boolean` | false |
6 changes: 3 additions & 3 deletions docs/docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ const config = {
playgroundPosition: 'bottom',
},
navbar: {
// title: 'Hooks studio',
title: 'React Use Custom Hooks',
logo: {
alt: 'Hooks studio logo',
src: 'img/h2.svg',
alt: 'Home page of react use custom hooks',
src: 'img/logo.png',
},
items: [
// {
Expand Down
2 changes: 1 addition & 1 deletion docs/src/components/HookDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function HookDetails() {
Usage
</h3>
<pre>
{`import {useSafeState} from 'react-use-custom-hooks';`}
{`import {useDebounce} from 'react-use-custom-hooks';`}
</pre>
</div>
</section>
Expand Down
8 changes: 3 additions & 5 deletions docs/src/pages/index.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@
background: rgb(255, 45, 116);
color: white !important;
}
/* .buttons a:hover {
transform: translate3d(0px, -2px, 0px);
box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 6px 0px;
transition: all 150ms linear 0s;
} */
.buttons a:hover {
background: #e24053;
}
4 changes: 2 additions & 2 deletions docs/src/theme/ReactLiveScope/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@

import React from 'react';
import { useDebounce, useSafeState, useIsMounted, usePrevious, useLegacyState } from "react-use-custom-hooks";
import { useDebounce, useSafeState, useIsMounted, usePrevious, useLegacyState, useTitle, useIsOnline } from "react-use-custom-hooks";

// Add react-live imports you need here
const ReactLiveScope = {
React,
...React,
useDebounce, useSafeState, useIsMounted, usePrevious, useLegacyState
useDebounce, useSafeState, useIsMounted, usePrevious, useLegacyState, useTitle, useIsOnline
};

export default ReactLiveScope;
Expand Down
Binary file modified docs/static/img/favicon.ico
Binary file not shown.
74 changes: 0 additions & 74 deletions docs/static/img/h2.svg

This file was deleted.

Binary file added docs/static/img/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 11 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,15 @@ import { useSafeState } from './useSafeState';
import { useIsMounted } from './useIsMounted';
import { usePrevious } from './usePrevious';
import { useLegacyState } from './useLegacyState';
import { useTitle } from './useTitle';
import { useIsOnline } from './useIsOnline';

export { useDebounce, useSafeState, useIsMounted, usePrevious, useLegacyState };
export {
useDebounce,
useSafeState,
useIsMounted,
usePrevious,
useLegacyState,
useTitle,
useIsOnline,
};
29 changes: 29 additions & 0 deletions src/useIsOnline.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useCallback } from 'react';
import { useState } from 'react';
import { useEffect } from 'react';

export function useIsOnline(): Boolean {
const isNavigatorOnLineDefined: boolean =
typeof window.navigator.onLine === 'boolean';
const [isOnline, setIsOnline] = useState<boolean>(window.navigator.onLine);

const onStatusChange = useCallback(
() => setIsOnline(window.navigator.onLine),
[]
);

useEffect(() => {
if (!isNavigatorOnLineDefined) {
return;
}
window.addEventListener('online', onStatusChange);
window.addEventListener('offline', onStatusChange);

return () => {
window.removeEventListener('online', onStatusChange);
window.removeEventListener('offline', onStatusChange);
};
}, []);

return isOnline;
}
25 changes: 25 additions & 0 deletions src/useTitle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { useEffect, useRef } from 'react';

interface Options {
restoreOnUnmount?: boolean;
}

const DEFAULT_OPTIONS: Options = {
restoreOnUnmount: false,
};

export function useTitle(
title: string,
options: Options = DEFAULT_OPTIONS
): void {
const isDocumentDefined = typeof document !== 'undefined';
const originalTitle = useRef(isDocumentDefined ? document.title : '');

useEffect(() => {
if (!isDocumentDefined) return;
if (document.title !== title) document.title = title;
return () => {
if (options?.restoreOnUnmount) document.title = originalTitle.current;
};
}, [title]);
}
Loading

0 comments on commit 36082c2

Please sign in to comment.