Redux CRUD Manager provide a simple way to sync your redux store with your remote server.
No more need to write actions and reducer to update your store.
What precisely each manager ?
- It use CRUD pattern
- update your data localy (redux store)
- update your data localy AND sync at the same time to your remote server
- update your data localy, and save few moment later to your remote server
- indicate loading process to the user (for example with a loader). No need to manually set a
isLoading
flag. - fetch your data and use local data (redux) if resource are already fetched.
Reudx Crud Manager do not include any library around redux, and do not provide any UI component. It only provide actions and reducer.
Install from npm registry
npm install redux-crud-manager --save
import { createManager } from 'redux-crud-manager';
const config = {...};
const usersManager = createManager(config);
-
reducerPath
{array[string]} - required - Most of time, there is a single item: the reducer name. But is you have nested reducer, define the full path. -
remoteActions
{object} - required - async action for HTTP request -
idKey
{string} - optional - the key use as the unique identifier. Default:id
-
cache
{bool | function} - enable cache if resources are already fetched. Default:false
You can pass a function to customise the check:
{
cache: (existingItems) => existingItems[0] && existingItems[0].bookId === someBookId
}
-
merge
{bool} optional - defaulttrue
- merge item property on update() -
replace
{bool} optional - defaultfalse
-
remote
{bool} optional - default:false
- save your change in your server, with remoteActions -
prefixLocalId
{string} - optional -
showUpdatingProgress
{bool} optional - defaulttrue
.syncing
will be set totrue
-
updateLocalBeforeRemote
{bool} optional - defaultfalse
. Properties will be updated locally before the server response. Ignored ifshowUpdatingProgress
is false -
forceDelete
{bool} optional - defaulttrue
-
includeProperties
{array[string]} optional - include property on save. -
excludeProperties
{array[string]} optional - include property on save. Ignored ifincludeProperties
is defined
import { createManager } from 'redux-crud-manager';
const config = {
reducerPath: ['users'],
remoteActions: {
fetchAll: () => {...}
fetchOne: () => {...}
create: () => {...}
update: () => {...}
delete: () => {...}
}
}
const usersManager = createManager(config);
How to create a user localy into redux store ?
const user = {name: ...};
dispatch(usersManager.actions.create(user));
Well, but with many users ?
Use an array:
const users = [{name: ...}, {name: ...}];
dispatch(usersManager.actions.create(users));
How to create on my remote server ?
Use {remote: true}
:
dispatch(usersManager.actions.create(users, {remote: true}));
Here is what happens above:
- POST request to your server
- redux store update after the request response
The POST request is defined in your remoteActions.create() function in the configuration. See How configure remoteActions
Now, if I want to do many changes localy, and sync my changes with my remote server few minutes later ?
// update my first user
dispatch(usersManager.actions.update({id: 1, name: ...}));
// create a third user
dispatch(usersManager.actions.create({name: ...}));
// delete my second user
dispatch(usersManager.actions.delete(userId));
// ... and few minute later, you want to save your data on your server
dispatch(usersManager.actions.sync());
Here is what happens above:
- PATCH (or PUT) request to your server (update the first user)
- POST request to your server (create the thrid user)
- DELETE request to your server (delete the second user)
- redux store update after all requests response
The sync()
function check which local resource was updated without {remote: true}
option, and make the appropriate request for it (create, update or delete).
ReducCrudManager use metadata to keep the state of your resource sync with your server, and know which resource need to be synced (created, updated or deleted).
Ok, nice. But how I can notify my user that my application is making a server request, in order to show a loader ? Use metadata.
import { getMeta } from 'redux-crud-manager';
const user = store.getState().users.find(...);
if (getMeta(user).syncing) {
// show loader
}
metadata are defined for a resource, and also for the list of resources:
import { getMeta } from 'redux-crud-manager';
const users = store.getState().users;
if (getMeta(users).syncing) {
// show loader
}
Why we need to use getMeta(user).synced
instead of user.synced
?
Because metadata is store into a key symbol in order to prevent conflict var name.
List of all metadata:
key | values | description |
---|---|---|
syncing | true / false | indicated if local data is currently syncing into server |
synced | true / false | indicated if local data is synced with server data |
fetching | true / false | only for resources list, not a single resource |
fetched | true / false | only for resources list, not a single resource |
nextSync | create / update / delete | indicated what is the next action for sync the local data to the server |
- save time of the last sync
- use delay for cache fetching