Skip to content

Instantly share code, notes, and snippets.

@fijiwebdesign
Last active February 10, 2017 18:17
Show Gist options
  • Save fijiwebdesign/d303940554c74d1cae75d25c8ba29fea to your computer and use it in GitHub Desktop.
Save fijiwebdesign/d303940554c74d1cae75d25c8ba29fea to your computer and use it in GitHub Desktop.
React HOC example from React Docs
/**
* 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)
// 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