0.9.2 • Published 4 years ago

redux-companion v0.9.2

Weekly downloads
9
License
-
Repository
-
Last release
4 years ago

Redux Companion

GitHub GitHub package version npm bundle size (minified + gzip) npm Travis Codecov FOSSA Status

Opinionated way to reduce boilerplate on async (or sync) logic, like fetching data etc. Zero dependency (Although it only makes sense to use together with Redux AND Redux Thunk).

Installation

npm i redux-companion

Why?

I find myself exhausted of writing (or copying) a lot of the same set of redux state, reducer, actions, and thunks for interacting with the api, so I thought why not make it easier?

Quick Start

See example usage.

Let's recreate Redux Todo List example with redux-companion and Ducks pattern.

Reducers

reducers/todos.js

import { createAction, createReducer } from 'redux-companion';

export const addTodo = createAction('ADD_TODO');
export const toggleTodo = createAction('TOGGLE_TODO');

const handlers = {
  [addTodo]: (state, payload) => [
    ...state,
    {
      id: payload.id,
      text: payload.text,
      completed: false
    }
  ],
  [toggleTodo]: (state, payload) =>
    state.map(todo => (todo.id === payload ? { ...todo, completed: !todo.completed } : todo))
};
const todo = createReducer(handlers, []);
export default todo;

reducers/visibilityFilter.js

import { createAction, createReducer } from 'redux-companion';

export const setVisibilityFilter = createAction('SET_VISIBILITY_FILTER');

export const VisibilityFilters = {
  SHOW_ALL: 'SHOW_ALL',
  SHOW_COMPLETED: 'SHOW_COMPLETED',
  SHOW_ACTIVE: 'SHOW_ACTIVE'
};

const handlers = {
  [setVisilibityFilter]: (state, payload) => payload
};
const visibilityFilter = createReducer(handlers, []);
export default visibilityFilter;

Not too much different, eh? But for me it's slightly better and less boilerplate. How about async actions (with Redux Thunk)?

Let's actually save our todo list to the server.

services/api.js

import axios from 'axios';
export const putTodos = todos => axios.put(`${BASE_URL}/todos/`, todos).then(res => res.data);

reducers/todos.js

import {
  createAction,
  createReducer,
  createAsyncActions,
  asyncInitialState,
  createAsyncHandlers
} from 'redux-companion';
import { createAsyncThunk } from 'redux-companion/dist/thunk';
import { putTodos } from '../services/api';

// ...
const saveTodosActions = createAsyncActions('SAVE_TODOS');
const saveTodos = createAsyncThunk(saveTodosActions, putTodos);
const sync = () => (dispatch, getState) => {
  const {
    todos: { list }
  } = getState();
  dispatch(saveTodos(list));
};

const initialState = {
  list: [],
  save: asyncInitialState
};

const handlers = {
  // ...
  ...createAsyncHandlers(saveTodosActions, { path: ['save'] })
};

const todos = createReducer(handlers, initialState);

export default todos;

And that's it, when you dispatch the sync() action, the todos are automatically saved to the server 🙌

Also, you can select the async state with the selectors:

import { createAsyncSelectors } from 'redux-companion';
const savingState = createAsyncSelectors(saveTodosActions);

// ...

const isSaving = savingState.isLoading;
const savingResponse = savingState.getData;

License

FOSSA Status

0.9.2

4 years ago

0.9.1

4 years ago

0.8.0

4 years ago

0.7.1

5 years ago

0.7.0

5 years ago

0.6.3

5 years ago

0.6.2

6 years ago

0.6.1

6 years ago

0.6.0

6 years ago

0.5.1

6 years ago

0.5.0

6 years ago

0.4.1

6 years ago

0.4.0

6 years ago

0.3.1

6 years ago

0.3.0

6 years ago

0.2.0

6 years ago

0.1.8

6 years ago

0.1.7

6 years ago

0.1.6

6 years ago