kadirahq / mantra

Mantra - An Application Architecture for Meteor
https://kadirahq.github.io/mantra/
978 stars 52 forks source link

What are the advantages of using 'injectDeps' to load the layout into the route? #145

Open THPubs opened 8 years ago

THPubs commented 8 years ago

Earlier, without using Mantra, I used this method to load the layouts :

FlowRouter.route('/', {
  name: 'home',
  action () {
    mount(MainLayout, { content: (<Home />) });
    setTitle();
  },
});

But when following a tutorial, I saw they using injectDeps to load the layout. What is the difference and what's the most preferred method?

export default function (injectDeps, {FlowRouter}) {
  const MainLayoutCtx = injectDeps(Layout);
  FlowRouter.route('/', {
    name: 'items.list',
    action() {
      mount(MainLayoutCtx, {
        content: () => (<ItemList />)
      });
    }
  });
}
fermuch commented 8 years ago

The only difference is that with injectDeps you have the context available in your Layout.

jkhoffman commented 7 years ago

Which context? The application context defined in client/configs/context.js? How do I access it from my layout?

I'm trying to get the current route from FlowRouter in my layout. Can't figure out how to get FlowRouter from the app context in my layout component.

v-anyukov commented 7 years ago

U can get context from first argument in composer function in your container, like so https://github.com/mantrajs/mantra-sample-blog-app/blob/master/client/modules/core/containers/postlist.js#L5 , and get FlowRouter (or Meteor, or Collections etc) from object returned by context() call.

jkhoffman commented 7 years ago

Yeah, I knew how to access the application context from the container, but I could not figure out how to access it from my main layout template.

Last night, I finally figured it out.

const AppLayout = ({ content }, reactContext) =>
  <main className={reactContext.context.FlowRouter.current().route.name}>
    {content()}
  </main>;

AppLayout.contextTypes = {
  context: PropTypes.object,
};

AppLayout.propTypes = {
  content: PropTypes.func,
};

The key was to define AppLayout.contextTypes. Once that is defined, the React context gets passed as the second parameter to the layout component. Mantra's app context gets passed inside that, as simply 'context'. So, reactContext.context is the Mantra app context.