1.0.2 • Published 6 years ago

react-context-api v1.0.2

Weekly downloads
8
License
MIT
Repository
github
Last release
6 years ago

react-context-api

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

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.

1.0.2

6 years ago

1.0.1

6 years ago

1.0.0

6 years ago

0.0.1

6 years ago