Skip to content

Commit

Permalink
chore(*): initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
dispix committed Oct 28, 2018
0 parents commit 6c9ca82
Show file tree
Hide file tree
Showing 12 changed files with 329 additions and 0 deletions.
45 changes: 45 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

# Created by https://www.gitignore.io/api/node

### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# Dependency directories
node_modules/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env

# End of https://www.gitignore.io/api/node
5 changes: 5 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"semi": false,
"singleQuote": true,
"trailingComma": "all"
}
197 changes: 197 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
# 🏴‍☠️ React Pirate

## _Hooks for React 16.7 and above. Arrrr._

## Installation

With [`npm`](https://npmjs.org/):

```
npm install react-pirate
```

With [`yarn`](https://yarnpkg.com/):

```
yarn add react-pirate
```

## Usage

### Utility hooks

- `usePrevious` stores a value so you can compare it to the current value ! Quite useful to store a piece of props or state and compare changes between renders:

```jsx
import React, { useState } from 'react'
import { usePrevious } from 'react-pirate'

function Pirate(props) {
const [shipCount, setShipCount] = useState(props.ship ? 1 : 0)
const previousShip = usePrevious(props.ship)

if (props.ship && previousShip !== props.ship) {
setShipCount(shipCount + 1)
}

switch (shipCount) {
case 0:
return <p>I am an aspiring pirate !</p>
case 1:
return <p>I have served on one ship !</p>
default:
return (
<p>I am a veteran pirate. I have served on {shipCount} ships !</p>
)
}
}
```

- `useTimeout` and `useInterval` are using for timing:

```jsx
import React, { useState } from 'react'
import { useTimout, useInterval, usePrevious } from 'react-pirate'

function Pirate(props) {
const [currentTime, setCurrentTime] = useState(0)
const [previousTime, setPreviousTime] = useState(0)
const previousShip = usePrevious(props.ship)

if (props.ship !== previousShip) {
setPreviousTime(currentTime)
}

setInterval(() => setCurrentTime(currentTime + 1000), 1000)

return (
<div>
<p>I've been serving on this ship for {currentTime} seconds !</p>
{previousTime && (
<p>
Before that, I served on {previousShip} for {previousTime} seconds !
</p>
)}
</div>
)
}
function Ship(props) {
useTimeout(() => {
if (props.isAtSee) {
props.returnToPort()
}
}, 1000)
return (
<p>{props.name} can't sail for too long or it'll run out of water!</p>
)
}
```
- ... More to come !
### Lifecycle hooks
Lifecycle hooks helps you simulate your good ol' `React.Component` lifecycle methods with hooks. These hooks use `useEffect` internally, but you can specify another React hook if needed :

- `componentDidMount`:

```jsx
import React, { useLayout } from 'react'
import { useMount } from 'react-pirate'
function Ship(props) {
useMount(() => {
// quite similar to `componentDidMount`
})
return <p>This is my Ship, it's name is {props.name}</p>
}
function Captain(props) {
useMount(
() => {
// similar to `componentDidMount`
},
{ hook: useLayout },
)
return <p>This is the captain of the {props.shipName} !</p>
}
```

- `componentDidUpdate`:

```jsx
import React, { useLayout } from 'react'
import { useUpdate, useLegacyUpdate } from 'react-pirate'
function Ship(props) {
useUpdate(() => {
// quite similar to `componentDidUpdate`
})
return <p>This is my Ship, it's name is {props.name}</p>
}
function Captain(props) {
useUpdate(
() => {
// similar to `componentDidUpdate`
},
{ hook: useLayout },
)
return <p>This is the captain of the {props.shipName} !</p>
}
```

- `componentWillUnmount`:

```jsx
import React, { useLayout } from 'react'
import { useUnmount, useLegacyUnmount } from 'react-pirate'
function Ship(props) {
useUnmount(() => {
// quite similar to `componentWillUnmount`
})
return <p>This is my Ship, it's name is {props.name}</p>
}
function Captain(props) {
useUnmount(
() => {
// similar to `componentWillUnmount`
},
{ hook: useLayout },
)
return <p>This is the captain of the {props.shipName} !</p>
}
```

- `getDerivedStateFromProps` has no need for hook ! Just update your state in your component:

```jsx
import React from 'react'
import { useState } from 'react'
function Firstmate(props) {
const [captain, setCaptain] = useState(null)
if (!captain && props.ship) {
setCaptain(props.ship.captain)
}
return <p>I am the first mate of captain {captain.name} until my death !</p>
}
```

- `getSnapshotBeforeUpdate`, `getDerivedStateFromError`, `componentDidCatch`: 🏳️ We surrender ! [React does not provide solutions for these hooks yet](https://reactjs.org/docs/hooks-faq.html#do-hooks-cover-all-use-cases-for-classes).

```
```
3 changes: 3 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as lifecycle from "./src/lifecycle";

export { lifecycle };
26 changes: 26 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "react-pirate",
"version": "1.0.0",
"description": "Sets of useful hooks for react 16.7 and above",
"main": "index.js",
"scripts": {
"test": "test"
},
"repository": {
"type": "git",
"url": "git+ssh://[email protected]/dispix/react-pirate.git"
},
"keywords": [
"react",
"library"
],
"author": "Octave \"dispix\" Raimbault <[email protected]>",
"license": "ISC",
"bugs": {
"url": "https://github.com/dispix/react-pirate/issues"
},
"homepage": "https://github.com/dispix/react-pirate#readme",
"peerDependencies": {
"react": ">=16.7.0-alpha.0"
}
}
6 changes: 6 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export { default as useMount } from './useMount'
export { default as useUpdate } from './useUpdate'
export { default as useUnmount } from './useUnmount'
export { default as useInterval } from './useInterval'
export { default as useTimout } from './useTimout'
export { default as usePrevious } from './usePrevious'
8 changes: 8 additions & 0 deletions src/useInterval.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { useEffect } from 'react'

export default function useInterval(fn, delay) {
useEffect(() => {
const id = setInterval(fn, delay)
return () => clearInterval(id)
})
}
5 changes: 5 additions & 0 deletions src/useMount.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { useEffect } from 'react'

export default function useMount(fn, { hook = useEffect } = {}) {
hook(() => void fn(), [])
}
9 changes: 9 additions & 0 deletions src/usePrevious.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { useEffect } from 'react'

export default function usePrevious(value) {
const ref = useRef()
useEffect(() => {
ref.current = value
})
return ref.current
}
8 changes: 8 additions & 0 deletions src/useTimeout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { useEffect } from 'react'

export default function useTimeout(fn, delay) {
useEffect(() => {
const id = setTimeout(fn, delay)
return () => clearTimeout(id)
})
}
5 changes: 5 additions & 0 deletions src/useUnmount.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { useEffect } from 'react'

export default function useUnmount(fn, { hook = useEffect } = {}) {
hook(() => fn, [])
}
12 changes: 12 additions & 0 deletions src/useUpdate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useRef, useEffect } from 'react'

export default function useUpdate(fn, { hook = useEffect } = {}) {
const mounting = useRef(true)
hook(() => {
if (mounting.current) {
mounting.current = false
} else {
fn()
}
})
}

0 comments on commit 6c9ca82

Please sign in to comment.