Package Exports
- react-redux-provide
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (react-redux-provide) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
react-redux-provide
This small library allows you to:
Build your entire app's view layer first - i.e., all your components become as "dumb" as possible.
Decorate your components with
@provide, which allows you to specify - aspropTypes- exactly the data and actions said components need.When mounting your app, assign providers to your components as necessary.
Pros
- Maximum separation of concerns.
- Use packaged providers for common use-cases or even build apps around specific providers.
- Quickly and easily switch out one provider for another.
- Enforces clean and efficient design.
- Extremely predictable and easy to understand.
- Reduces boilerplate.
- No need for
context(i.e,react-redux's<Provider>component)! - Looks good in
react-devtools!

Cons
- You tell me!
Installation
npm install react-redux-provide --saveUsage
The API surface area is naturally tiny. There are just 3 exports, but you probably only need to concern yourself with the following 2 functions:
provide(propTypes)- The decorator which allows you to assign providers to components.assignProviders(initialState?, providers, components)- Assigns providers to components of course! Optionally initialize the store's state. Check the source for exact usage.
Caveats
Components can have multiple providers, but the provided
props(actionsandreducers) should be unique to each provider.When assigning a provider to components, it will automatically create a new store for you if you haven't explicitly included a
storekey within yourproviderobject. Said store is shared throughout the components passed toassignProviders. You can of course callassignProvidersmultiple times to create multiple stores as necessary.Specify all of your
propTypes! Theprovidedecorator filters out anypropsnot within yourpropTypes, which keeps things efficient and helps with avoiding unnecessary re-renders. Plus, it's good design!
Quick Example
Basically, create some component with only the view in mind, plus whatever props you'd expect to use for triggering actions. For this quick example, we know react-redux-provide-list provides a list prop and a pushItem function, so in our @provide decorator we'll make it clear that's what we want.
From examples/good-times/components/GoodTimes.js:
import React, { Component, PropTypes } from 'react';
import provide from 'react-redux-provide';
@provide({
list: PropTypes.arrayOf(PropTypes.object).isRequired,
pushItem: PropTypes.func.isRequired
})
export default class GoodTimes extends Component {
addTime() {
this.props.pushItem({
time: Date.now()
});
}
render() {
return (
<div className="good-times">
{this.renderButton()}
{this.renderTimes()}
</div>
);
}
renderButton() {
const style = {
fontSize: '20px',
marginBottom: '20px'
};
return (
<input
type="button"
style={style}
value="Let the good times roll"
onClick={::this.addTime}
/>
);
}
renderTimes() {
return this.props.list.map(
item => (
<li key={item.time}>
{new Date(item.time).toString()}
</li>
)
);
}
}Then when mounting the app, all we need to do is assign the provider(s) to the component(s). Let's create a file called init.js to do this:
import { assignProviders } from 'react-redux-provide';
import provideList from 'react-redux-provide-list';
import GoodTimes from './components/GoodTimes';
const list = provideList();
const initialState = {
list: [
{ time: Date.now() }
]
};
assignProviders(initialState, { list }, {
GoodTimes
});And last but not least, all we have to do is import init.js when rendering the app. From index.js:
import './init';
import React from 'react';
import { render } from 'react-dom';
import GoodTimes from './components/GoodTimes';
render(<GoodTimes/>, document.getElementById('root'));Creating Providers
A provider is just an object with a few properties. At its core, it's your usual redux actions and reducers, which you'll typically need at a bare minimum. There are a few other things you can optionally include:
name- Defaults to its corresponding key within theprovidersargument of yourassignProviderscall. This will show up inreact-devtools- e.g., if you providelistandmaptoSomeComponent, in your dev tools, you'll seeSomeComponentwrapped with another component calledProvideSomeComponent(list,map).middleware- Include whatever middleware is used by your provider. This can be either an array of middlewares or a single middleware.enhancer- Include whatever enhancer is used by your provider's store. This can be either an array of enhancers or a single enhancer.merge(stateProps, dispatchProps, parentProps)- This incredibly useful function should return an object, which typically adds, removes, or replaces certain provided properties based on whatever logic you deem necessary. For example, inreact-redux-provide-list, if the component has anindexprop passed to its parent and expects anitemprop from the provider, themergefunction will attempt to provide theitemat thatindexwithin thelistto the component.store- This is your typicalreduxstore. See the Caveats section above about automatically generated stores.mapState- Maps each reduced state to the providedprops. By default, it will map them all. It's unlikely that you'll ever actually need to include this, as the providedpropsare filtered based on the component'spropTypes.mapDispatch- It's unlikely that you'll need to include this as well. This defaults todispatch => bindActionCreators(actions, dispatch)or if it's an object, it will useredux'swrapActionCreators.
Notes
You'll probably notice that many providers have everything in a single file. It makes sense for the simple ones, but you can of course structure everything however you want since it's ultimately just a single object.
You don't have to use generic provider packages. Feel free to create a providers directory in your app and structure your exports however you like!
You'll also notice that no constants are exported. There's a good reason for this. Your components should have no knowledge of the constants used within your actions and reducers, which leads to a maximum separation of concerns and is always the best design. Your components should care about only 2 things: what to render and which actions to call.