react-context-api

1.0.2 • Public • Published

react-context-api

!!!The library is not stable now!!!

npm version Coverage Status license mit circle ci

This is a React 16.3 context api wrapper. The purpose of the library is giving a convenience way to use Context API as a react global store.

Basic Usage

Create your context (store) like below format. It is good to define by features.

// todos.jsx
import { createContext, Component } from 'react'
const cx = createContext({});
class Provider extends Component {
  constructor(props) {
    super(props);
    this.state = {
      todos: [],
      actions: {
        addTodo: this.addTodo
      }
    };
  }
 
  addTodo = todo => {
    this.setState(prev => ({todos: prev.todos.concat(todo)}));
  };
 
  render(){
    return (
      <cx.Provider value={this.state}>{this.props.children}</cx.Provider>
    );
  }
}
 
export default {
  Provider: Provider,
  Consumer: cx.Consumer
};
 
// other.jsx
import { createContext, Component } from 'react'
const cx = createContext({});
class Provider extends Component {
  constructor(props) {
    super(props);
    this.state = {
      other: [],
      actions: {
        otherAction: this.otherAction
      }
    };
  }
 
  otherAction = () => {
    // do something...
  };
 
  render(){
    return (
      <cx.Provider value={this.state}>{this.props.children}</cx.Provider>
    );
  }
}
 
export default {
  Provider: Provider,
  Consumer: cx.Consumer
};

Render Props

Inject context to your App by ContextProvider and consume by ContextConsumer

import createContextAPI from 'react-context-api';
import todos from './todos';
import others from './others';
 
const { ContextProvider, ContextConsumer } = createContextAPI({ todos, others });
 
const Child = props => (
  // you can specific fields by `contextToRenderProps` prop like
  // <ContextConsumer contextToRenderProps={['todos']}>
  // the render props will only get the `todos` field.
  <ContextConsumer>
    {({ todos, others }) => (
      <div>
        <ul>{todos.todos.map(todo => <li>{todo}</li>)}</ul>
        <button onClick={evt => todos.actions.addTodo('new todo')}>ADD</button>
      </div>
    )}
  </ContextConsumer>
);
 
const App = props => (
  <ContextProvider>
    <Child />
  <ContextProvider/>
);

HOC

If you prefer HOC styles, you can use withContextProvider and withContextConsumer.

You can use render props api and HOC api together.

const { withContextProvider, withContextConsumer } = createContextAPI({
  todos,
  others
});
 
const Child = withContextConsumer(['todos', 'others'])(({ todos, others }) => (
  <div>
    <ul>{todos.todos.map(todo => <li>{todo}</li>)}</ul>
    <button onClick={evt => todos.actions.addTodo('new todo')}>ADD</button>
  </div>
));
 
const App = withContextProvider(Child);

API Reference

createContextAPI(contextList: Object) => ({ContextProvider, ContextConsumer, withContextProvider, withContextConsumer, getContextConsumer})

contextList must be a object which value is a context pair ({ Provider, Consumer }):

import { createContext, Component } from 'react'
const cx = createContext({});
class Provider extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  render(){
    return (
      <cx.Provider value={this.state}>{this.props.children}</cx.Provider>
    );
  }
}
const contextPair {
  Provider: Provider,
  Consumer: cx.Consumer 
};
 
const contextList = { contextName: contextPair }

A render-props api which provider the context into your App.

You can get your context in your component anywhere through <ContextConsumer /> API.

Props

  • contextToRenderProps<string[]>: specific fields that you want to consume. If no contextToRenderProps is supplied or contextToRenderProps is an empty array, it will return all context instead.

withContextProvider(Component) => WrapperedComponent

Same as <ContextProvider/>, but use HOC styling. Inject the context into Component.

withContextConsumer(contextToRenderProps: string[]) => (Component) => WrapperedComponent

Same as <ContextConsumer />, but use HOC styling. The specific fields will be injected as props into your Component.

getContextConsumer(field: string[]) => ContextConsumerWithoutContextToRenderProps

If you prefer get Consumer with specific field statically instead of changing with contextToRenderProps props dynamically. You can use getContextConsumer directly. It will return a <ContextConsumer /> component with specific context and no contextToRenderProps prop.

Readme

Keywords

Package Sidebar

Install

npm i react-context-api

Weekly Downloads

41

Version

1.0.2

License

MIT

Unpacked Size

47.4 kB

Total Files

7

Last publish

Collaborators

  • chiahao