react-context-api
v1.0.2
Published
react 16.3 context api utils
Downloads
111
Readme
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 orcontextToRenderProps
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.