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.
- Host: GitHub
- URL: https://github.com/shalimov/react-hooks-combine
- Owner: Shalimov
- License: mit
- Created: 2019-04-18T11:53:23.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2023-01-04T21:43:58.000Z (over 3 years ago)
- Last Synced: 2024-11-19T15:57:20.542Z (over 1 year ago)
- Topics: api, api-wrapper, hooks, hooks-wrapper, react, reactjs, recompose, structure
- Language: JavaScript
- Homepage:
- Size: 1.62 MB
- Stars: 9
- Watchers: 3
- Forks: 1
- Open Issues: 12
-
Metadata Files:
- Readme: readme.md
- Changelog: CHANGELOG.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
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...__