Skip to content

Instantly share code, notes, and snippets.

@jshimko
Last active October 3, 2017 04:26
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jshimko/6232d90baa1ec890a3722f1ba88a8a77 to your computer and use it in GitHub Desktop.
Save jshimko/6232d90baa1ec890a3722f1ba88a8a77 to your computer and use it in GitHub Desktop.
Container/Component Patterns
/**
* Container
*/
import { compose, withProps } from 'recompose';
import { graphql } from 'react-apollo';
import gql from 'graphql-tag';
import { withPermissions, withIsAdmin, composeWithTracker } from '/client/api';
import UserDashboard from '../components/dashboard';
import usersListQuery from '../graphql/usersList.graphql';
// Meteor subscription with react-komposer
const composer = (props, onData) => {
if (Meteor.subscribe('orders').ready()) {
const orders = Orders.find().fetch();
onData(null, { orders });
}
};
// GraphQL query for a list of users
const usersListQuery = gql`
query users {
users {
_id
username
email
}
}
`;
// an object with any amount of random helper methods
// that will show up as props in the wrapped component
const helpers = {
alertHello: () => alert("Hello!"),
deleteUser: (id) => Users.remove(id)
};
// finally, export a wrapped component with data, helpers, and permission check props
export default compose(
composeWithTracker(composer),
graphql(usersListQuery),
withProps(helpers),
withPermissions(["perms", "to", "check"]),
withIsAdmin(),
)(UserDashboard);
/**
* Component
*/
import { Component } from "react";
class UserDashboard extends Component {
render() {
// grab the injected props
const {
// from withPermissions
canCreate,
canView,
canUpdate,
canDelete,
// from withIsAdmin
isAdmin,
// helper methods
alertHello,
deleteUser,
// data from GraphQL query
data: { loading, users },
// data from Meteor subscription
orders
} = this.props;
// use the react-apollo loading helper
if (loading) {
return <Spinner/>;
}
return (
<div>
{/* check read access to something */}
{canView
? <span>Top secret thing</span>
: <span>Sorry, you do not have access to this!</span>
}
{/* use one of the helper methods */}
<Button onClick={alertHello}>Say Hello</Button>
{/* user table with edit/delete buttons */}
<table>
{
users.map((u) => (
<tr key={u._id}>
<td>
{u.username}
{canUpdate && <Button>Edit</Button>}
{canDelete || isAdmin ?
<Button onClick={() => deleteUser(u._id)}>Delete User</Button>
: null}
</td>
</tr>
));
}
</table>
...and so on
</div>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment