Skip to content

Instantly share code, notes, and snippets.

@lorennorman
Last active June 22, 2021 16:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lorennorman/cf8ffb024f48efd25e8fd0797180e8d7 to your computer and use it in GitHub Desktop.
Save lorennorman/cf8ffb024f48efd25e8fd0797180e8d7 to your computer and use it in GitHub Desktop.
React: convert class -> functional component
// Class Style
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { createStructuredSelector } from 'reselect';
import { compose } from 'redux';
import injectReducer from 'utils/injectReducer';
import injectSaga from 'utils/injectSaga';
import reducer from './reducer';
import saga from './sagas';
import makeSelectHackerNews from './selectors';
import { fetch } from './actions';
class HackerNews extends React.PureComponent {
componentDidMount() {
const { hackerNews } = this.props;
if (!hackerNews.data.length && !hackerNews.fetching) {
this.props.fetch({
offset: 0,
limit: 15,
});
}
}
render() {
const { fetching, data, error } = this.props.hackerNews;
return this.props.children.call(null, {
fetching,
data,
error,
});
}
}
HackerNews.propTypes = {
hackerNews: PropTypes.object.isRequired,
children: PropTypes.func.isRequired,
fetch: PropTypes.func.isRequired,
};
const mapStateToProps = createStructuredSelector({
hackerNews: makeSelectHackerNews(),
});
function mapDispatchToProps(dispatch) {
return {
fetch: (data) => dispatch(fetch(data)),
};
}
const withConnect = connect(
mapStateToProps,
mapDispatchToProps,
);
const withReducer = injectReducer({ key: 'hackerNews', reducer });
const withSaga = injectSaga({ key: 'hackerNews', saga });
export default compose(
withReducer,
withSaga,
withConnect,
)(HackerNews);
// Functional Style: half the size!
import PropTypes from 'prop-types'
import { useSelector, useDispatch, shallowEqual } from 'react-redux'
import makeSelectHackerNews from './selectors'
import { fetch } from './actions'
function useHackerNews(props) {
const hackerNews = useSelector(makeSelectHackerNews, shallowEqual)
const dispatch = useDispatch()
useEffect(() => {
if (!hackerNews.data.length && !hackerNews.fetching) {
dispatch(fetch({
offset: 0,
limit: 15,
}))
}
}, [hackerNews])
return hackerNews
}
export default function HackerNews({ children, ...props }) {
const hackerNews = useHackerNews(props)
return children(hackerNews)
}
HackerNews.propTypes = {
children: PropTypes.func.isRequired,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment