npm package: @iris-platform/incontext
Description: Light state management based on React context API
Author: Rob Sliwa
Latest version: 1.0.5

# Incontext

Light state management library based on React context API.

Incontext attempts to mimic react-redux interface. While the interface is very
similar there some minor differences to watch out, primarily in area of creating
Provider's store.

To see how to use `incontext` in React application see `examples/todo`. This
todo app is virtually copied line by line from redux.js.org website and shows
how easy it is to use `incontext` instead of react-redux.

# Installing

This library uses React's context APIs so it requires React 16.3 or higher.

To install `incontext`:

```
npm install --save incontext
```

# Manual

## Provider

You should wrap your React application with Provider component. Provider component
expects store property to be passed to it. Store contains reducers as well as
initial state for each reducer.

Use `createStore` utility function to convert your reducers to proper store object:

```jsx
import { createStore } from '@iris-platform/incontext';
const store = createStore([Todo, User, Teams]);
```

Here Todo, User, Teams are reducers. `createStore` accepts array of reducer objects
and converts them to store representation.

```jsx
import { Provider, createStore } from '@iris-platform/incontext';

const store = createStore([Todo]);

const App = () => (
  <Provider store={store}>
    ...
  </Provider>
);
```

## Reducers

Reducer objects describe how state changes in response to actions.

```jsx
const initialState = {
  visibilityFilter: SHOW_ALL,
  todos: []
};

const Todo = (state = initialState, action) => {
  switch (action.type) {
    case SET_VISIBILITY_FILTER:
      return {
        ...state,
        visibilityFilter: action.filter
      };

    case ADD_TODO:
      return {
        ...state,
        todos: [
          ...state.todos,
          {
            text: action.text,
            completed: false
          }
        ]
      };

    case TOGGLE_TODO:
      return {
        ...state,
        todos: state.todos.map((todo, index) => {
          if (index === action.index) {
            return {
              ...todo,
              completed: !todo.completed
            };
          }
          return todo;
        })
      };

    default:
      return state;
  }
};

export default Todo;
```

You will always need to define `initialState` with initial values. Provider will
use these values to set its initial state.

Just like in react-redux we do not mutate the state we copy the state object
with updated values.

## Actions

Actions are functions that deliver specific payloads to `incontext` store.
Incontext store updates in response to the reducer receiving the new payload
from incoming action.

```jsx
const TodoActions = {
  addTodo: text => {
    return {
      type: ADD_TODO,
      text
    };
  },
  toggleTodo: index => {
    return {
      type: TOGGLE_TODO,
      index
    };
  },
  setVisibilityFilter: filter => {
    return {
      type: SET_VISIBILITY_FILTER,
      filter
    };
  }
};
```

## Components & Containers
Incontext provides the `connect` utility function for creating container components from presentational components. Below is an example usage. See the [redux documentation](https://redux.js.org/basics/usagewithreact#presentational-and-container-components) for a complete discussion of component types.
```jsx
import { connect } from '@iris-platform/incontext';

const MyComponent = ({ name, onClick }) => (
  <div onClick={onClick}>Hello {name}!</div>
)

const mapStateToProps = state => ({
  name: state.firstName,
})

const mapDispatchToProps = dispatch => ({
  onClick: name => dispatch({ type: 'CLICK', name }),
});

const mergeProps = (stateProps, dispatchProps, ownProps) => ({
  ...stateProps,
  ...dispatchProps,
  onClick: () => dispatchProps.onClick(stateProps.name),
})

export default connect(
  mapStateToProps,
  mapDispatchToProps,
  mergeProps,
)(MyComponent);
```

## Examples

Checkout [examples](https://github.com/iris-platform/incontext/tree/master/examples) folder for sample usage of `incontext`.

# Contributing

If you find a bug, please [create an issue](https://github.com/iris-platform/incontext/issues/new) providing instructions to reproduce it. It's always very appreciable if you find the time to fix it. In this case, please [submit a PR](https://github.com/iris-platform/incontext/pulls).