Last active
October 3, 2017 04:26
-
-
Save jshimko/6232d90baa1ec890a3722f1ba88a8a77 to your computer and use it in GitHub Desktop.
Container/Component Patterns
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
/** | |
* 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 | |
} | |
} | |
`; | |
// 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); |
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
/** | |
* 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