Skip to content

Instantly share code, notes, and snippets.

@pmg103
Created December 19, 2018 21:00
Show Gist options
  • Save pmg103/817cea61a850c3a5879488fc51d61e8c to your computer and use it in GitHub Desktop.
Save pmg103/817cea61a850c3a5879488fc51d61e8c to your computer and use it in GitHub Desktop.
Use render props to isolate loading/collection from component
const ActivityEdit = ({activity, updateActivity, response}) => (
<div>
<h1>Welcome to {activity.get('name')}</h1>
<button
onClick={() => updateActivity(Map({name: 'New name'}))}
disabled={isPending(response)}
>
Update name
</button>
</div>
);
const ActivityListCreate = ({activity, createActivity, response}) => (
<div>
<h1>Activities</h1>
<ul>
{activities.map(activity =>
<li>{activity.get('name')}</li>
)}
</ul>
<button
onClick={() => createActivity(Map({name: 'New activity'}))}
disabled={isPending(response)}
>
Create activity
</button>
</div>
);
const App = ({ activityId }) => (
<div>
<WithItem type={ACTIVITIES} id={activityId} render={({item, update, response}) => (
<ActivityEdit
activity={item}
updateActivity={update}
response={response}
/>
)}/>
<WithCollection type={ACTIVITIES} render={({items, create, response}) => (
<ActivityListCreate
activities={items}
createActivity={create}
response={response}
/>
)}/>
</div>
);
class WithItem extends React.Component {
componentWillMount() {
const { type, id } = this.props;
this.props.loadItem(type, id);
}
render() {
const { type, id, render, items, responses } = this.props;
const isFetching = isPending(responses.getIn([GET_ITEM, type]));
const hasData = items.get(type) && items.getIn([type, 'id']) === id
if (isFetching && !hasData) {
return <Loading />;
}
return (
<span>
{isFetching && <Loading />}
{hasData && render({
item: items.get(type),
update: this.props.updateItem.bind(type),
response: responses.getIn([UPDATE_ITEM, type])
})}
</span>
);
}
}
function mapStateToProps(state) {
return {
items: state.items,
responses: state.responses,
};
}
export default connect(mapStateToProps, {loadItem, updateItem})(WithItem);
class WithCollection extends React.Component {
componentWillMount() {
const { type } = this.props;
this.props.getCollection(type);
}
render() {
const { type, id, render, collections, responses } = this.props;
const isFetching = isPending(responses.getIn([GET_COLLECTIONS, type]));
const hasData = collections.get(type);
if (isFetching && !hasData) {
return <Loading />;
}
return (
<span>
{isFetching && <Loading />}
{hasData && render({
collection: collections.get(type),
items: collections.getIn([type, 'items']),
create: this.props.createItem.bind(type),
response: responses.getIn([CREATE_ITEM, type])
})}
</span>
);
}
}
function mapStateToProps(state) {
return {
collections: state.collections,
responses: state.responses,
};
}
export default connect(mapStateToProps, {getCollection, createItem})(WithCollection);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment