Last active
August 29, 2015 14:23
-
-
Save gilbox/8b4ca88518150bc4dcb9 to your computer and use it in GitHub Desktop.
Functional React: component Function with ComponentRenderMixin and staticFunctionsMixin
This file contains hidden or 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
| // ComponentRenderMixin is a slightly modified version of PureRenderMixin | |
| const ComponentRenderMixin = require('component-render-mixin'); | |
| function delegate(delegee) { | |
| var delegate = function() { | |
| return delegate.delegee.apply(this, arguments); | |
| } | |
| delegate.delegee = delegee; | |
| delegate.isDelegate = true; | |
| return delegate; | |
| } | |
| function wrapWithDelegate (key) { | |
| var statics = this; | |
| var delegee = statics[key]; | |
| if (typeof delegee === 'function') { | |
| statics[key] = isDelegate(delegee) ? delegee : delegate(delegee); | |
| } | |
| } | |
| function isDelegate (value) { | |
| return value && value.isDelegate; | |
| } | |
| function componentWillMount () { | |
| var statics = this.props.statics; | |
| if (statics && typeof statics === 'object') { | |
| Object.keys(statics).forEach(wrapWithDelegate, statics); | |
| } | |
| } | |
| function componentWillReceiveProps (newProps) { | |
| var currentProps = this.props; | |
| var currentStatics = currentProps.statics; | |
| var newStatics = newProps.statics; | |
| var haveChangedStatics = newStatics !== currentStatics && | |
| newStatics && | |
| typeof newStatics === 'object'; | |
| if (haveChangedStatics) { | |
| Object.keys(newStatics).forEach(function(key) { | |
| var newMember = newStatics[key]; | |
| if (typeof(newMember) == 'function') { | |
| var currentMember = currentStatics && currentStatics[key]; | |
| if (isDelegate(currentMember)) { | |
| var delegee = isDelegate(newMember) ? newMember.delegee : newMember; | |
| currentMember.delegee = delegee; | |
| newStatics[key] = currentMember; | |
| } else { | |
| newStatics[key] = delegate(newMember); | |
| } | |
| } | |
| }); | |
| } | |
| } | |
| const staticFunctionsMixin = { | |
| componentWillMount, | |
| componentWillReceiveProps | |
| }; | |
| // @param additionalMixins? {Array|Object} | |
| // @param renderFn {Function} | |
| // @returns Component | |
| function component(additionalMixins, renderFn) { | |
| renderFn = renderFn || additionalMixins; | |
| additionalMixins = (additionalMixins instanceof Function) ? [] : [].concat(additionalMixins); | |
| const mixins = [ComponentRenderMixin, | |
| staticFunctionsMixin] | |
| .concat(additionalMixins); | |
| const render = function() { | |
| console.log(`render <${renderFn.name} />`); | |
| return renderFn.call(this, this.props, this.props.statics, this.props.children); | |
| }; | |
| const displayName = renderFn.name; | |
| return React.createClass({displayName, mixins, render}); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment