npm package: @react-useful-hooks/use-mount
Description: react hook and component that supports to easily handle different renders between server side and client side.
Author: Eddie Choi
Latest version: 1.0.5

<p align='center'>
    <img src='/static/logo.png' width="300px" />
</p>

<p align='center'>
    <a href="https://github.com/ReactUsefulHooks/use-mount/blob/main/README.md">
        <img src="https://img.shields.io/badge/-ENGLISH-blueviolet?style=for-the-badge" />
    </a>
    <a href="https://github.com/ReactUsefulHooks/use-mount/blob/main/readme/README.ko.md">
        <img src="https://img.shields.io/badge/-KOREAN-violet?style=for-the-badge"/>
    </a>
</p>

<p align='center'>
  <!-- slack -->
  <a target="_blank" href="https://reactusefulhooks.slack.com">
    <img src="https://img.shields.io/badge/slack-reactusefulhooks-9cf.svg?logo=slack" alt="slack" />
  </a>
  <!-- package version -->
  <a target="_blank" href="https://npmjs.com/package/@react-useful-hooks/use-mount">
    <img src="https://img.shields.io/npm/v/@react-useful-hooks/use-mount" alt="npm package">
  </a>
  <!-- pull request -->
  <a target="_blank" href="https://github.com/ReactUsefulHooks/use-mount/pulls">
    <img src="https://img.shields.io/badge/PRs-welcome-lightgrey.svg?style=flat-square" alt="PR WELCOME" />
  </a>
  <!-- example -->
  <a target="_blank" href="https://github.com/ReactUsefulHooks/use-mount/tree/main/packages/playground">
    <img src="https://img.shields.io/badge/%F0%9F%92%A1-examples-ff615b.svg?style=flat-square" alt="example" />
  </a>
  <!-- downloads -->
  <a target="_blank" href="http://npm-stat.com/charts.html?package=@react-useful-hooks/use-mount&from=2023-04-07">
    <img src="https://img.shields.io/npm/dm/@react-useful-hooks/use-mount.svg?style=flat-square" alt="status" />
  </a>
  <!-- bundle size -->
  <a target="_blank" href=https://img.shields.io/bundlephobia/minzip/@react-useful-hooks/use-mount?color=blue>
    <img src="https://img.shields.io/bundlephobia/minzip/@react-useful-hooks/use-mount?color=yellow" alt="bundle size" />
  </a>
  <!-- supports -->
  <a>
    <img src="https://img.shields.io/badge/support-esm,cjs-black" alt="support" />
  </a>
</p>
<br />

# ☀ use-mount

## 📌 Table of contents

- 🔮 Preview
- 🚧 Problem
- 💡 Solution
- 🌈 API
- 📝 Example
- 🏆 Contributors
- 🚀 Contribution
- 🧑‍💻 Issues
- 🚧 License
- 🦄 Sponsors

## 🔮 Preview

`use-mount` provide react hook and component to handle rendering either server side or client side.

|Server Side|Client Side|
|:---------:|:-------:|
|![server-side](/static/server-side.png)|![client-side](/static//client-side.png)|

## 🚧 Problem

Using SSR in react, there are always cicumstances to control server side rendering(SSR). And there are components like NoSSR.
Although Nuxt.js support ClientOnly Component, Next.js does not support ClientOnly Component.

## 💡 Solution

useMount supports to easily handle server side rendering(SSR). <br />
use-mount package not only provide `react hook`, which can easily manipulate to not rendering specific component in server side, but also support `ClientOnly Component`, which known as NoSSR Component but has more controls.

```shell
# yarn
yarn add @react-useful-hooks/use-mount
# npm
npm install @react-useful-hooks/use-mount
```

## 🌈 API

use-mount package provide `useMount react hook` and `ClientOnly Component`.

```typescript
import { useMount, ClientOnly } from '@react-useful-hooks/use-mount';
```

### useMount

```typescript
type isMount = boolean;
type useMount = (callback?: () => void, deps?: any[]) => isMount;
```

#### useMount return type

| return  |  type   |                     description                     | default |
| :-----: | :-----: | :-------------------------------------------------: | :-----: |
| isMount | boolean | isMount value will turn true when hydration statred |  false  |

#### useMount param type

|  params  |   type   |                           description                            |  default  |
| :------: | :------: | :--------------------------------------------------------------: | :-------: |
| callback | function |          callback will be called when hydration started          | undefined |
|   deps   |  any[]   | any dependencies regarding callback function just like useEffect | undefined |

### ClientOnly

```typescript
type ClientOnly = ({
	children,
	fallback,
	fallbackTag,
	...delegates
}) => ReactElement;
```

#### ClientOnly props type

|    props    |            type             |                                  description                                   |  default  |
| :---------: | :-------------------------: | :----------------------------------------------------------------------------: | :-------: |
|  children   |        ReactElement         |                children will be rendered when hydration started                | undefined |
|  fallback   |   string or ReactElement    |                    fallback will be rendered at server side                    | undefined |
| fallbackTag | keyof JSX.IntrinsicElements |                  can switch parent tag such as h1, h2, ...etc                  |   'div'   |
|  delegates  |            any[]            | delagates are attributes for HTML tags such as label, aria-label, href, ...etc | undefined |

## 📝 Example

### useMount

```typescript
function Test() {
	const isMounted = useMount(() => {
		console.log('mounted!');
		return () => {
			console.log('unmounted!');
		};
	}, []);
}
```

### ClinetOnly

#### 1. Only rendering text

```typescript
function Test() {
	/**
	 * @description
	 * This Component will render
	 * <div>useMount</div>
	 * in server side.
	 */
	return (
		<ClientOnly fallback={'useMount'}>
			<div>hello</div>
		</ClientOnly>
	);
}
```

#### 2. Rendering with different tag

```typescript
function Test() {
	/**
	 * @description
	 * This Component will render
	 * <h1>useMount</h1>
	 * in server side.
	 */
	return (
		<ClientOnly fallback="useMount" fallbackTag="h1">
			<div>hello</div>
		</ClientOnly>
	);
}

// also you can pass any atrributes to fallback tag
function Test() {
	/**
	 * @description
	 * This Component will render
	 * <h1 aria-label='hello'>useMount</h1>
	 * in server side.
	 */
	return (
		<ClientOnly fallback="useMount" fallbackTag="h1" aria-label="hello">
			<div>hello</div>
		</ClientOnly>
	);
}
```

#### 3. Rendering Component

```typescript
function ServerSide() {
	return <h1>useMount</h1>;
}

function Test() {
	/**
	 * @description
	 * This Component will render
	 * <h1>useMount</h1>
	 * in server side.
	 */
	return (
		<ClientOnly fallback={<ServerSide />}>
			<div>hello</div>
		</ClientOnly>
	);
}
```

## 🏆 Contributors

Thanks goes to these wonderful people.

<p align='center'>
  <a target="_blank" href="https://github.com/eddie0329"><img width="150" src="https://github.com/eddie0329.png" alt="eddie0329"></a>
</p>

## 🚀 Contribution

> Looking to contribute? Look for the [Good First Issue label](https://github.com/ReactUsefulHooks/use-mount/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22).

Please make sure to read the [Contributing Guide](https://github.com/ReactUsefulHooks/use-mount/blob/main/CONTRIBUTING.md) before making any pull requests.

## 🧑‍💻 Issues

### 🐛 Bugs

Please post issue for bugs, missing documetations, or unexpected behavior

[Click for bug-report](https://github.com/ReactUsefulHooks/use-mount/issues/new?assignees=&labels=bug&template=bug-report.md)

### ⭐️ Feature Requests

Please post issue to suggest new features.

[Click for featrure-request](https://github.com/ReactUsefulHooks/use-mount/issues/new?assignees=&labels=enhancement&template=feature-request.md)

## 🚧 License

[MIT](https://opensource.org/licenses/MIT)

## 🦄 Sponsors

Become first sponsor this project!

> Check out more useful react hooks [here](https://github.com/ReactUsefulHooks). <br />
> If you have any questions, feel free to join our [slack](https://reactusefulhooks.slack.com)