Last active
February 10, 2017 18:17
-
-
Save fijiwebdesign/d303940554c74d1cae75d25c8ba29fea to your computer and use it in GitHub Desktop.
React HOC example from React Docs
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
/** | |
* What about a HOC that has multiple mixins | |
* The HOC if flattened from mixins | |
* The WrappedComponent is still decoupled from HOC | |
* todo: test | |
*/ | |
function mixinHoc(WrappedComponent, mixins) { | |
mixins = [].concat(mixins) | |
return React.createClass({ | |
mixins: mixins, | |
_child: null, | |
setRef: function(ref) { | |
console.log('setRef', ref) | |
this._child = ref | |
}, | |
render: function() { | |
console.log('Rending <WrappedComponent>', this.props, this.state) | |
return <WrappedComponent ref={this.setRef} {...this.props} {...this.state} />; | |
} | |
}); | |
} | |
var comments = [ | |
{id: 0, comment: 'Hello World!'} | |
] | |
var DataSource = { | |
addChangeListener: () => {}, | |
removeChangeListener: () => {}, | |
getComments: () => comments | |
} | |
var dataSourceMixin = { | |
getInitialState: function() { | |
return { | |
comments: DataSource.getComments() | |
}; | |
}, | |
componentDidMount: function() { | |
DataSource.addChangeListener(this.handleChange); | |
}, | |
componentWillUnmount: function() { | |
DataSource.removeChangeListener(this.handleChange); | |
}, | |
handleChange: function() { | |
var comments = DataSource.getComments() | |
console.log('Handle change for this', this, comments) | |
this.setState({ | |
comments: comments | |
}) | |
} | |
}; | |
function CommentList(props) { | |
var comments = props.comments; | |
return ( | |
<div> | |
{comments.map(function(comment) { | |
return <Comment comment={comment} key={comment.id} /> | |
})} | |
</div> | |
) | |
} | |
function Comment(props) { | |
return (<div id={'comment-' + props.comment.id}>{props.comment.comment}</div>) | |
} | |
var DataCommentList = mixinHoc(CommentList, dataSourceMixin); | |
var ref = null | |
var el = React.createElement(DataCommentList, { | |
ref: (_ref) => ref = _ref | |
}) | |
ReactDOM.render(el, document.getElementById('app')) | |
setTimeout(() => { | |
comments.push({id: 1, comment: 'Hello Darkness!'}) | |
ref && ref.handleChange() | |
console.log(el._child, el, ref) | |
}, 100) |
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
// https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html | |
function withSubscription(WrappedComponent) { | |
return React.createClass({ | |
getInitialState: function() { | |
return { | |
comments: DataSource.getComments() | |
}; | |
}, | |
componentDidMount: function() { | |
DataSource.addChangeListener(this.handleChange); | |
}, | |
componentWillUnmount: function() { | |
DataSource.removeChangeListener(this.handleChange); | |
}, | |
handleChange: function() { | |
this.setState({ | |
comments: DataSource.getComments() | |
}); | |
}, | |
render: function() { | |
// Use JSX spread syntax to pass all props and state down automatically. | |
return <WrappedComponent {...this.props} {...this.state} />; | |
} | |
}); | |
} | |
// Optional change: convert CommentList to a functional component | |
// because it doesn't use lifecycle hooks or state. | |
function CommentList(props) { | |
var comments = props.comments; | |
return ( | |
<div> | |
{comments.map(function(comment) { | |
return <Comment comment={comment} key={comment.id} /> | |
})} | |
</div> | |
) | |
} | |
// Instead of declaring CommentListWithSubscription, | |
// we export the wrapped component right away. | |
module.exports = withSubscription(CommentList); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment