Easily connect your React components to Flux stores
- remove boilerplate from your components
- map Flux stores to props instead of state
- ease your migration from Flux to Redux
npm install --save fludux
Fludux exports two higher order functions to connect to any Flux store:
connectToStore
and connectToStores
.
import { connectToStore, connectToStores } from 'fludux';
Additionally, Fludux provides store creation utility functions `createStore` and `createDispatcherCallback` that can help you create a store with a state reducer function. You do not have to use these in order to use `connectToStore` or `connectToStores`.
import { createStore, createDispatcherCallback } from 'fludux';
store
(object): your Flux store that exposes changelisteners
mapStateToProps
(function): map your stores' state to props
config
(object), optional: if your store exposes addChangeListener and removeChangeListener
but they have different names, you can set them here. See examples below.
storeMapping
(array{object}) : an array of objects with the following properties:
store
, mapStateToProps
, config
. They work simirlaly as connectToStore
arguments.
initialState
(object): the initial state object of your state.
E.g. {isLoading: false}
.
store
(object): created Flux store with methods emitChange
,
addChangeListener
, removeChangeListener
, getState
and setState
.
reducer
(function): a reducer function that gets previous state as first
parameter, and the action object as second parameter. Returns new state.
(See an example below).
Your React component connected to a Flux store without Fludux:
import MyStore from 'MyStore';
function getState() {
return {
someValue: MyStore.getSomeValue()
};
}
const MyComponent = React.createClass({
getInitialState() {
return getState();
},
componentWillMount() {
MyStore.addChangeListener(this.onChange);
},
componentDidUnmount() {
MyStore.removeChangeListener(this.onChange);
},
onChange() {
this.setState(getState());
},
render() {
return (
<div>{this.state.someValue}</div>
);
}
});
export default MyComponent;
Your React component with Fludux:
import { connectToStore } from 'fludux';
import MyStore from 'MyStore';
const MyComponent = React.createClass({
propTypes: {
someValue: React.PropTypes.string
},
render() {
return (
<div>{this.props.someValue}</div>
);
}
});
export default connectToStore(MyStore, store => ({
someValue: store.getSomeValue()
}))(MockComponent);
import { connectToStores } from 'fludux';
import MyStore1 from 'MyStore1';
import MyStore2 from 'MyStore2';
const MyComponent = React.createClass({
propTypes: {
someValue1: React.PropTypes.string,
someValue2: React.PropTypes.string
},
render() {
return (
<div>{this.props.someValue}</div>
);
}
});
export default connectToStores([
{
store: MyStore1,
mapStateToProps: Store => ({someValue1: Store.getSomeValue() })
},
{
store: MyStore2,
mapStateToProps: Store => ({someValue2: Store.getSomeValue() }),
config: {
addChangeListener: 'myCustomNameForAddChangeListener',
removeChangeListener: 'myCustomNameForRemoveChangeListener'
}
}
])(MockComponent);
import { createStore, createDispatcherCallback } from 'fludux';
import AppDispatcher from 'some/where/AppDispatcher';
const INITIAL_STATE = {isLoading: false};
const MyStore = createStore(INITIAL_STATE);
const myStoreReducer = function(state, action) {
switch (action.type) {
case 'LOADING_START':
return {
...state,
isLoading: true
};
case 'LOADING_DONE':
return {
...state,
isLoading: false
};
default:
return state;
}
}
AppDispatcher.register(createDispatcherCallback(
myStoreReducer,
MyStore
));
export default MyStore;
MIT