GithubHelp home page GithubHelp logo

miguelramosfdz / redux-storage Goto Github PK

View Code? Open in Web Editor NEW

This project forked from michaelcontento/redux-storage

0.0 1.0 0.0 82 KB

Persistence layer for redux with flexible backends

License: MIT License

Makefile 4.68% JavaScript 95.32%

redux-storage's Introduction

redux-storage

build dependencies devDependencies

license npm version npm downloads Code Climate

Save and load the Redux state with ease.

Features

  • Flexible storage engines
  • Storage engines can be async
  • Load and save actions that can be observed
    • SAVE: { type: 'REDUX_STORAGE_SAVE', payload: /* state tree */ }
    • LOAD: { type: 'REDUX_STORAGE_LOAD', payload: /* state tree */ }
  • Various engine decorators
  • Black- and whitelist actions from issuing a save operation

Installation

npm install --save redux-storage

Usage

import * as storage from 'redux-storage'

// Import redux and all your reducers as usual
import { createStore, applyMiddleware, combineReducers } from 'redux';
import * as reducers from './reducers';

// We need to wrap the base reducer, as this is the place where the loaded
// state will be injected.
//
// Note: The reducer does nothing special! It just listens for the LOAD
//       action and merge in the provided state :)
const reducer = storage.reducer(combineReducers(reducers));

// Now it's time to decide which storage engine should be used
//
// Note: The arguments to `createEngine` are different for every engine!
import createEngine from 'redux-storage/engines/reactNativeAsyncStorage';
const engine = createEngine('my-save-key');

// And with the engine we can create our middleware function. The middleware
// is responsible for calling `engine.save` with the current state afer
// every dispatched action.
//
// Note: You can provide a list of action types as second argument, those
//       actions will be filtered and WON'T trigger calls to `engine.save`!
const middleware = storage.createMiddleware(engine);

// As everything is prepared, we can go ahead and combine all parts as usual
const createStoreWithMiddleware = applyMiddleware(middleware)(createStore);
const store = createStoreWithMiddleware(reducer);

// At this stage the whole system is in place and every action will trigger
// a save operation.
//
// BUT (!) an existing old state HAS NOT been restored yet! It's up to you to
// decide when this should happen. Most of the times you can/should do this
// right after the store object has been created.

// To load the previous state we create a loader function with our prepared
// engine. The result is a function that can be used on any store object you
// have at hand :)
const load = storage.createLoader(engine);
load(store);

// Notice that our load function will return a promise that can also be used
// to respond to the restore event.
load(store)
    .then((newState) => console.log('Loaded state:', newState))
    .catch(() => console.log('Failed to load previous state'));

Details

Engines

reactNativeAsyncStorage

This will use AsyncStorage out of react-native.

import createEngine from 'redux-storage/engines/reactNativeAsyncStorage';
const engine = createEngine('my-save-key');

Warning: react-native is not a dependency of redux-storage! You have to install it separately.

localStorage

Stores everything inside window.localStorage.

import createEngine from 'redux-storage/engines/localStorage';
const engine = createEngine('my-save-key');

Warning: localStorage does not expose a async API and every save/load operation will block the JS thread!

Warning: Some browsers like IE<=11 does not support Promises. For this you might use localStorageFakePromise which should work too - BUT other parts of redux-storage might depend on Promises too! So this is a possible workaround for very limited cases only. The best solution is to use a polyfill like es6-promise.

Actions

redux-storage will trigger actions after every load or save operation from the underlying engine.

You can use this, for example, to display a loading screen until the old state has been restored like this:

import { LOAD, SAVE } from 'redux-storage';

function storeageAwareReducer(state = { loaded: false }, action) {
    switch (action.type) {
        case LOAD:
            return { ...state, loaded: true };

        case SAVE:
            console.log('Something has changed and written to disk!');

        default:
            return state;
    }
}

Middleware

If you pass an array of action types as second argument to createMiddleware, those will be added to a internal blacklist and won't trigger calls to engine.save.

import { createMiddleware } from 'redux-storage'

import { APP_START } from './constants';

const middleware = createMiddleware(engine, [ APP_START ]);

If you want to whitelist all actions that are allowed to issue a engine.save, just specify them as third argument.

import { createMiddleware } from 'redux-storage'

import { SHOULD_SAVE } from './constants';

const middleware = createMiddleware(engine, [], [ SHOULD_SAVE ]);

Decorators

Decorators simply wrap your engine instance and modify/enhance it's behaviour.

Filter

Use this decorator to write only part of your state tree to disk.

import { decorators } from 'redux-storage'

engine = decorators.filter(engine, [
    'simple-key',
    ['nested', 'key'],
    ['another', 'very', 'nested', 'key']
]);

Debounce

This decorator will delay the expensive save operation for the given ms. Every new change to the state tree will reset the timeout!

import { decorators } from 'redux-storage'

engine = decorators.debounce(engine, 1500);

Immutablejs

Convert parts of the state tree into Immutable objects on engine.load.

import { decorators } from 'redux-storage'

engine = decorators.immutablejs(engine, [
    ['immutablejs-reducer'],
    ['plain-object-reducer', 'with-immutablejs-key']
]);

Todo

  • Write tests for everything!

redux-storage's People

Contributors

cef62 avatar dbachrach avatar gasperz avatar greenkeeperio-bot avatar jdlehman avatar miracle2k avatar romanenko avatar skevy avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.