Last active
October 1, 2015 00:05
-
-
Save goatslacker/5f84bf1793cbc7badda3 to your computer and use it in GitHub Desktop.
The new alt connect?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class InfoView extends React.Component { | |
render() { | |
return <div>{this.props.things}</div> | |
} | |
} | |
export default connect({ | |
listenTo() { | |
return [InfoStore] | |
}, | |
getProps(props, context) { | |
return { | |
things: InfoStore.fetchInfo(), | |
} | |
} | |
}, InfoView) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { PropTypes } from 'react' | |
import { Resolver } from 'react-resolver' | |
import isPromise from 'is-promise' | |
function connect(spec, Component) { | |
return React.createClass({ | |
displayName: `Stateful${Component.displayName || Component.name}Container`, | |
contextTypes: { | |
flux: React.PropTypes.object | |
}, | |
getInitialState() { | |
this.flux = this.context.flux | |
this.stores = this.flux ? this.flux.stores : {} | |
this.spec = typeof spec === 'function' | |
? spec(this.stores, this.flux) | |
: spec | |
return this.getNextState() | |
}, | |
componentWillMount() { | |
if (this.spec.willMount) this.call(this.spec.willMount) | |
}, | |
componentDidMount() { | |
const stores = this.spec.listenTo ? this.call(this.spec.listenTo) : [] | |
this.storeListeners = stores.map((store) => { | |
return store.listen(() => this.setState(this.getNextState())) | |
}) | |
if (this.spec.didMount) this.call(this.spec.didMount) | |
}, | |
componentWillUnmount() { | |
this.storeListeners.forEach(unlisten => unlisten()) | |
if (this.spec.willUnmount) this.call(this.spec.willUnmount) | |
}, | |
componentWillReceiveProps(nextProps) { | |
if (this.spec.willReceiveProps) this.call(this.spec.willReceiveProps) | |
this.setState(this.getNextState(nextProps)) | |
}, | |
shouldComponentUpdate(nextProps) { | |
return this.spec.shouldComponentUpdate | |
? this.call(this.spec.shouldComponentUpdate) | |
: true | |
}, | |
call(f, props = this.props) { | |
return f(props, this.context, this.flux) | |
}, | |
getNextState(nextProps = this.props) { | |
const reduced = this.spec.getProps | |
? this.call(this.spec.getProps, nextProps) | |
: nextProps | |
const { | |
props, | |
resolve, | |
} = Object.keys(reduced).reduce((obj, key) => { | |
const prop = reduced[key] | |
if (isPromise(prop)) { | |
obj.resolve[key] = () => prop | |
} else { | |
obj.props[key] = prop | |
} | |
return obj | |
}, { | |
props: {}, | |
resolve: {}, | |
}) | |
return { props, resolve } | |
}, | |
render() { | |
return ( | |
<Resolver props={this.state.props} resolve={this.state.resolve}> | |
{resolved => { | |
return <Component {...resolved} flux={this.flux} /> | |
}} | |
</Resolver> | |
) | |
}, | |
}) | |
} | |
export default connect |
cc @ericclemmons this uses react-resolver to resolve the async props. I still have yet to make this work universally but that's the next step. Hopefully I can get rid of Render then.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
cc @taion @lelandrichardson @cpsubrian
A couple of comments about this new connect.js which is meant to replace connectToStores.
enhance()
method is a way to hook into connectToStores so you can inject all kinds of other props, not sure this method should exist but I do have a couple of use cases for it. If it does exist theenhance
name is awful, what's a better one?