Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/rkrupinski/redux-resource-factory
Handle resources like a boss 😎.
https://github.com/rkrupinski/redux-resource-factory
Last synced: about 1 month ago
JSON representation
Handle resources like a boss 😎.
- Host: GitHub
- URL: https://github.com/rkrupinski/redux-resource-factory
- Owner: rkrupinski
- Created: 2019-10-22T11:27:49.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2023-01-04T23:14:22.000Z (almost 2 years ago)
- Last Synced: 2024-10-13T12:52:20.360Z (2 months ago)
- Language: TypeScript
- Homepage:
- Size: 212 KB
- Stars: 2
- Watchers: 3
- Forks: 1
- Open Issues: 11
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# redux-resource-factory
[![CircleCI](https://circleci.com/gh/rkrupinski/redux-resource-factory.svg?style=svg)](https://circleci.com/gh/rkrupinski/redux-resource-factory)
Handle resources like a boss 😎.
[API](#api) | [Examples](#examples)
`redux-resource-factory` provides useful abstraction over [redux](https://redux.js.org/)-managed resources that:
* are (typically) asynchronous
* succeed / fail
* might get cancelled / resetUsage:
```typescript
import { createStore } from "redux";
import { createResource } from "redux-resource-factory";const { reducer, request, success } = createResource("USERS");
const store = createStore(reducer);
type AppState = ReturnType; // Resource
store.getState(); // { data: null, error: null, loading: false }
store.dispatch(request());
store.getState(); // { data: null, error: null, loading: true }
store.dispatch(success({ data: [] }));
store.getState(); // { data: [], error: null, loading: false }
```## API
### `Resource`
Represents a resource of type `T` that can fail with an error of type `E`.
```typescript
type Resource = {
data: T | null;
error: E | null;
loading: boolean;
};
```### `resource(init?)`
Used to create instances of `Resource`.
Arguments:
* `init?: Partial>` - overrides (default values used otherwise)
Returns:
```typescript
Resource
```The default values are:
```typescript
{
data: null,
error: null,
loading: false,
}
```### `createResource(tag, options?)`
Used to create a reducer for managing the particular resource, along with corresponding action creators.
Arguments:
* `tag: string` - a unique string identifier of a resource (used internally to filter corresponding actions)
* `options?: { initialState?: Resource }` - additional options (currently only include specifying initial state)Returns:
```typescript
{ reducer, ...actionCreators }
```where `reducer` has the following signature:
```typescript
(
state: Resource | undefined,
action: ReturnType
) => Resource;
```and the `actionCreators` are:
#### `request()`
```diff
{
data: null,
error: null,
- loading: false,
+ loading: true,
}
```#### `success(payload: { data: T })`
```diff
{
- data: null,
+ data: [{...}, {...}],
error: null,
- loading: true,
+ loading: false,
}
```#### `error(payload: { data: E })`
```diff
{
data: null,
- error: null,
+ error: "Unauthorized",
- loading: true,
+ loading: false,
}
```#### `reset()`
```diff
{
- data: [{...}, {...}],
+ data: null,
error: null,
loading: false,
}
```#### `cancel()`
```diff
{
data: null,
error: null,
- loading: true,
+ loading: false,
}
```## Examples
### With [redux-thunk](https://github.com/reduxjs/redux-thunk)
```typescript
export const fetchUser = (
userId: User["id"],
cancel: Deferred
): ThunkAction, AppState, any, AnyAction> => async dispatch => {
dispatch(request());try {
const { data } = await axios.get(
`/users/${userId}`,
{
cancelToken: new CancelToken(c => cancelDefer.promise.then(() => c())),
}
);dispatch(
success({ data })
);
} catch (err) {
dispatch(
isCancel(err)
? cancel()
: error({ data: err })
);
}
};
```### With [redux-saga](https://redux-saga.js.org/)
```typescript
function* fetchUserSaga(action: SomeAction) {
const source = axios.CancelToken.source();yield put(request());
try {
const { data } = yield call(
axios.get,
`/users/${action.payload.userId}`,
{ cancelToken: source.token },
);yield put(success({ data }));
} catch (err) {
yield put(error({ data: err }));
} finally {
if (yield cancelled()) {
yield put(cancel());source.cancel();
}
}
}
```