An open API service indexing awesome lists of open source software.

https://github.com/shalimov/react-hooks-combine

Hooks powered, recompose like utility belt for ladies and gentlemen.
https://github.com/shalimov/react-hooks-combine

api api-wrapper hooks hooks-wrapper react reactjs recompose structure

Last synced: 12 months ago
JSON representation

Hooks powered, recompose like utility belt for ladies and gentlemen.

Awesome Lists containing this project

README

          

# React hooks combine

[Hooks](https://reactjs.org/docs/hooks-intro.html) powered, recompose like utility belt for ladies and gentlemen.

---

React Hooks Combine (RHC) is a simple utility belt to help you split up logic for your components between container (smart) part and dummy component (view) part.
It helps you to create only one [__HOC__](https://reactjs.org/docs/higher-order-components.html) effortlessly with [__custom hook__](https://reactjs.org/docs/hooks-custom.html) which combines all listed [HOOKS](https://reactjs.org/docs/hooks-intro.html) (all in one).

It has API Design similar to [Recompose](https://github.com/acdlite/recompose).

---
## Documentation
Documentation can be found here: [API Reference](/docs/api-reference.md)

You can improve it by sending pull requests to this repository.

---
## Let's Get Started

__Prerequisites:__
- [React >= 16.8.0](https://reactjs.org/)
- __[yarn](https://yarnpkg.com/ru/)__ _or_ __npm__

__Install (choose preferable way)__
- `yarn add react-hooks-combine`
- `npm install react-hooks-combine`

__Then...__

```javascript
import React from 'react'

import { withState, pipe, withCallbacks } from 'react-hooks-combine'

const useCount = pipe(
withState('count', 'setCount', 0),
// try to not forget about dependencies since it's hooks, not a hocs
withCallbacks({
increment: ({ count, setCount }) => () => setCount(count + 1),
decrement: ({ count, setCount }) => () => setCount(count - 1),
})
)

function Counter() {
const { count, increment, decrement } = useCount()

return (


-1
{count}
+1

)
}

export default Counter
```

__OR__

```javascript
import { pipe, withAsyncEffect, withCallbacks } from 'react-hooks-combine'

const useCurrentUser = pipe(
withContext('repository', RepositoryContext),
withAsyncEffect({
deps: [],
dataName: 'details',
loadingName: 'loading',
async asyncAction({ repository } /* state */, props) {
const { userRepository } = repository
const details = await userRepository.getCurrentUser()
return details
}
}),
// check withCallbacks section for syntax
withCallbacks({
onDelete: () => () => {
...
},

onUpdate: {
deps: [...],
func: () => () => {},
},
}, [...]),
)

export const UserView = (props) => {
// useCurrentUser is a custom hook
// and returns object which contains properties:
// details, onDelete, onUpdate, loading, repository
// details contains info that comes from some external source by async request
const user = useCurrentUser(props)

return (


Hello {user.details.firstName


...
Update
Delete

)
}
```

__OR__

```javascript
// component.jsx
import React from 'react'

export const UserPageComponent = ({ loading, userData, onSubmit, onCancel }) => (


User Form



{
() => (

)
}


)
```

```javascript
// container.js (withAsyncEffect + withCallbacks)
import { combine, withAsyncEffect, withCallbacks } from 'react-hooks-combine'

import { UserPageComponent } from './component'

export default combine(
withAsyncEffect({
deps: ['userId'], // will request again if user id is changed
dataName: 'userData', // 'data' by default
asyncAction: (_state, ownProps) => ownProps.userService.load(ownProps.userId),
}),
withCallbacks({
onSubmit: (state, props) => async (formData) => {
const { userData } = state
const { userService } = props

await userService.save({ ...userData, ...formData})
...
},

onCancel: () => () => {
...
}
}, ['userData'])
)(UserPageComponent)

```

__OR__

```javascript
// component.jsx
import React from 'react'

export const CounterComponent = ({ count, onPlus, onMinus }) => (


Active: {count}
+
-

)
```

```javascript
// container.js (withReducer + withCallbacks)
import { combine, withReducer, withCallbacks } from 'react-hooks-combine'

import { CounterComponent } from './component'

const INC = 'INC'
const DEC = 'DEC'

const reducer = (count, action) => {
switch(action.type) {
case INC: return count + 1
case DEC: return count - 1
default: return count
}
}

export default combine(
withReducer({
reducer,
stateName: counterState,
initialState: 0,
}),
withCallbacks({
onPlus: ({ counterState, dispatch }, _props) => () => {
dispatch({ type: INC })
},

onMinus: ({ counterState, dispatch }, _props) => () => {
dispatch({ type: DEC })
}
}, ['counterState']), // <- deps for useCallback (CHECK API TO LEARN MORE)
)(CounterComponent)

```
__OR__

```javascript
// container.js (withState + withCallbacks)
import { combine, withState, withCallbacks } from 'react-hooks-combine'

import { CounterComponent } from './component'

export default combine(
withState('count', 'setCount', 0),
withCallbacks({
onPlus: ({ count, setCount }, _props) => () => {
setCount(count + 1)
},

onMinus: ({ setCount }, _props) => () => {
setCount(count => count - 1) // function could be used
}
}, ['count']), // <- deps for useCallback (CHECK API TO LEARN MORE)
)(CounterComponent)
```

__OR WHICHEVER YOU LIKE...__