I had already settles on this connector pattern in my apps, where I put my connector junk (withTracker, redux, etc.) in a connectors
folder, and then use those as reusable components throughout my app. It looked like this:
// UPDATE: I added some fixes for SSR, and to make sure to use userId
// instead of user for iLoggedIn check, to avoid problems during startup,
// like premature redirects
export const withAccount = withTracker((props) => {
const user = Meteor.isServer ? null : Meteor.user()
const userId = Meteor.isServer ? null : Meteor.userId()
return { account: {
user,
userId,
isLoggedIn: !!userId
} }
})
Since withTracker
returns a HoC, which accepts another component, I can then reuse the same code anywhere I needed the data it provides by wrapping my one off components.
const SideBarAccountInfo = withAccount((props) => <div>Account SideBar</div>)
const HeaderAccountInfo = withAccount((props) => <div>Account Header</div>)
// ...etc.
In many cases this is pretty good. I have some data types like a “pages and parts” collection, which can take a property for the document id, at whatever depth I need it, without doing a tone of prop drilling.
But sometimes, the data isn’t unique, as in the example above - it always is she same data, so it’s a tiny bit wasteful to pull that data out every time I need it. With React’s new context API, I can create a Provider and Consumer, and only pull the data once!
import { Meteor } from 'meteor/meteor'
import React from 'react'
import { withTracker } from 'meteor/react-meteor-data'
const AccountContext = React.createContext('account')
export const withAccount = withTracker((props) => {
const user = Meteor.isServer ? null : Meteor.user()
const userId = Meteor.isServer ? null : Meteor.userId()
return { account: {
user,
userId,
isLoggedIn: !!userId
} }
})
function Provider (props) {
return <AccountContext.Provider value={props.account}>
{props.children}
</AccountContext.Provider>
}
export const AccountProvider = withAccount(Provider)
export const AccountConsumer = AccountContext.Consumer
So now I can add the account data once using the provider, and use the consumer to pull out the data from that single source. Yay!
What do you think?