-
-
Notifications
You must be signed in to change notification settings - Fork 15.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Document how people can benefit from observable spec interop #1718
Comments
As I understand it, it's literally just to make a Redux store act as an observable source if you already happen to be using observables in your project. If you're not using RxJS or Bacon or similar, it's irrelevant for you. |
Parts of my app are pulling in RxJS so I'm interested if I could avoid I'm familiar with Rx, but I don't know how to efficiently mix it with Redux. |
|
React Redux does more than you might think. Just for fun, here's a back-of-the-envelope (in other words, I scribbled this down without actually running it, so there are probably some mistakes) implementation of import { PropTypes } from 'react'
import compose from 'recompose/compose'
import getContext from 'recompose/getContext'
import shallowEqual from 'recompose/shallowEqual'
import mapPropsStream from 'rx-recompose/mapPropsStream'
import { bindActionCreators } from 'redux'
const defaultMergeProps = (stateProps, dispatchProps, ownProps) => ({
...ownProps,
...stateProps,
...dispatchProps
})
const connect = (mapStateToProps, mapDispatchToProps, mergeProps = defaultMergeProps) =>
compose(
// Get store from context
getContext({ store: PropTypes.object }),
mapPropsStream(ownProps$ => {
const store$ = ownProps$.pluck('store').first()
// Subscribe to state updates
const stateProps$ = store$
.flatMap(store => store)
.withLatestFrom(ownProps$, mapStateToProps)
.distinctUntilChanged(null, shallowEqual) // Compare props to prevent unnecessary re-renders
// Bind action creators
const dispatch$ = store$.pluck('dispatch')
let dispatchProps$
if (typeof mapDispatchToProps === 'function') {
dispatchProps$ = ownProps$
.withLatestFrom(dispatch$, (props, dispatch) =>
mapDispatchToProps(dispatch, props)
)
} else {
const actionCreators = mapDispatchToProps
dispatchProps$ = dispatch$
.map(dispatch => bindActionCreators(actionCreators, dispatch))
}
// Combine into single stream of props
return ownProps$.combineLatest(
stateProps$, dispatchProps$, dispatch$
(ownProps, stateProps, dispatchProps, dispatch) => ({
...mergeProps(stateProps, dispatchProps, ownProps)
dispatch
})
)
})
) And this is only a partial implementation :) In most React apps, I'd say you're better off sticking with React Redux and dealing with the entire props object as a stream instead: const enhance = compose(
connect(selector, actionCreators), // React Redux
mapPropsToStream(props$ => {
// Selected state is part of props. Go crazy.
return childProps$
})
)
const EnhancedComponent = enhance(BaseComponent) |
If anyone actually does want to add a docs section on this, please comment here and let me know. Until then, closing due to inactivity. |
PR #1632 introduced observable spec to the store.
I'd be very interested in how I can use or benefit from that feature in my code, but I can't find any kind of documentation or example.
The text was updated successfully, but these errors were encountered: