deflux
A declarative FLUX architecture for React
Features
- Flux architecture
- Support multiple stores
- Support declarative syntax
- Support pure function for action / render / component / reducer
- Support linked props
- Support computed props
- Support wired actions for store
- Support many prop sources: Store, Own Props, State, Promise, Literal
- Update store props/reducers/middleware on demand
- Compatible with Redux store/reducer/middleware
- Compatible with Rxjs
Samples
https://codesandbox.io/s/j30rxwnww9
References
create(factory, ...describers)
Create an object which is built by factory method and describers
update(target, ...describers)
store(initialState)
Create store factory with initialState
component(renderMethodOrComponentClass)
Create component factory. create() will return HOC instead Component if no renderMethodOrComponentClass specified
Store: withProp(stateProp, fromStore(parentStore), parentProp)
Declare linked store prop which is linked to a specific prop of parent store. Once parent store updated, all linked props of child stores will update as well. Remark: When You update linked props of child stores, parent store's props will update as well. This is 2 ways binding. It is helpful to create an action can update multiple stores. For sample: Imaging you have 2 stores, one for todo ids, other for todo texts. You want to update both stores with an action
const IdStore = ;const TextStore = ;const TodoStore = ;const AddTodoAction = { const id = ; return ...state // append id to id list ids: ...stateids id // set new text to texts hash texts: ...statetexts id: text ;};TodoStore;
Store: withProp(stateProp, fromProp(...propNames), computer)
Declare computed store prop which can be computed from one or many props.
;
Store: withReducer(...reducers)
Declare reducer for the store. Reducer is function, it retrieves (state, action, payload) => newState. Reducer will be called if there is any action creator called. There are two kinds of action. One can modify state and other only create action payload only.
const MyActionCreator = text;// when an action returns a function, it will retrieve state as an argument and it becomes state modifier.// No reducer can handle this action typeconst MyStateModifierAction = text ;const MyReducer = state action payload if action === MyActionCreator // do something and return new state return ...state text: payload ; return state;;MyStore;
Store: withMiddleware(...middleware)
Declare middleware for the store. Middleware is a curry function, it retrieves store => next => (action, payload) => newState
Component: withProp(name, propSource, map)
Declare component prop, there are two prop sources: fromStore and fromProp (owned props). You can specific the prop retrieves value from one or more Stores
;
You can specific the prop retrieves value from one or more owned props.
;
You also specific multiple props at once.
;
Component: withAction(name, store, action, payloadFactory)
Declare wired action as component prop.
const MyStore = ;const MyAction = { ; // no change return state;};const Component = ;
You can pass payloadFactory to produce new payload from calling context and input args.
Calling context has some props: ownProps (the original props retrieved from parent component),
mappedProps (the props that component will be used to render)
payloadFactory has prototype:
(arg1, arg2, ...) => payload.
(arg1, arg2, ...) => callingContext => payload.
;
Connect Redux store to component
const ReduxIncreaseActionType = 1;const ReduxDecreaseActionType = 2;const ReduxIncreaseActionCreator = type: ReduxIncreaseActionType ;const ReduxDecreaseActionCreator = type: ReduxDecreaseActionType ;const ReduxReducer = state = 100 action if actiontype === ReduxIncreaseActionType return state + 1; if actiontype === ReduxDecreaseActionType return state - 1; return state;; const ReduxStore = ; const ReduxComponent = ;
Map observable value to component prop
import fromEvent from "rxjs";const source = ; const MouseInfo = ;