Hi All,
DISCLAIMER: this is going to be a long question, I apologize.
I am new to meteor, so I also apologize if the questions are a bit naive.
I have some troubles figuring out the best way to handle data in conjunction with react and react router.
Last disclaimer: I manage to achieve the kind of result that I need but this is not a question about how to simply achieve the result, is a question trying to understand what are the best practices that I should follow.
So far I understood that one pattern is to have the router point to root components that use createContainer to fetch some data and pass it to children components. I have seen this pattern in the react todoList on github (https://github.com/meteor/todos/tree/react) and mentioned in the guide and on the forums as well.
However I have several things that are not really clear in my mind especially regarding the connection between routes, RootContainers (the components that implement createContainer) and presentational components. They are all related to each other, so more than an answer question by question I would also appreciate if somebody can give me a generic high level overview of how an application components hierarchy and routes should be setup to have the best results in terms of code reuse, performance, maintanability, etc.
CreateContainer asks to specify as a parameter the react component to which the data will be passed to in the props. How do I share the same container between multiple children? The only way I can think of is to have createContainer point to a middle-layer ParentComponent that will then clone and render its children (similar to what the AppContainer does in the react todo github) . But to me it looks like a lot of boilerPlate code, is there anything more simple if I simple want two presentational components to both access the same collection? Do I really have to always create an intermediate component to pass to createContainer that just clones and renders the children?
Let’s assume I want to achieve this kind of components hierarchy and 2 collections, Categories and Products, where there are multiple products in one category. (linked by categoryId)
<MainUI> <CategoriesPage/> <AllProductsPage/> <ProductsInCategoryPage/> <ProductDetailPage/> </MainUI>
where the whole app needs to have access to the loggedIn user, CategoriesPage needs to have access to the entire categories collection, AllProductsPage need to have access to all products collection, ProductsInCategoryPage need to have access to the Products in one category, and ProductDetailPage needs to have access to a specific product.
How Would I setup this in terms of react components and routes?
The mainUI could be a rootContainer that uses createContainer to register to the meteor user data, passes it to a rootLayout that renders the title, the theme, and clones&render the children.
But what about the other pages?
Should we register to products&categories collection also in the mainUI and then pass it down to the children? This would require potentially passing it through children that don’t really care about that data, and moreover would always listen to all the collections in any page in the app, so I don’t like it.
Should we have a “CategoriesContainer” and a “ProductsContainer” as children of MainUI, and these two have the other pages as children? That would work for CategoriesPage, AllProductsPage and ProductDetailPage, but what for ProductsInCategoryPage that needs both?
Should each one of the pages be a rootComponent with its own createContainer call, even if they share most of the data? Aside for being super verbose (creating a lot of container components for the same collections), how would this behave with meteor? I mean, in that case there would be a container fetching all categories, one fetching all products, one fetching all products with a certain categoryID, and the last container fetching a product with a certain productId. How would this work if a user visits all the pages? Would the data be fetched multiple times? Or would it be fetched only once and then just queried locally from minimongo? Would the 4 createContainers reactive functions be less performing than having a single one, even if they listen to the same collections?
Or should we set it up even differently?
Another question:
What if I know that some of those collections will be pretty static and I don’t want to reactively listen on them but just fetch them once? Should I still put the find() inside a createContainer just to listen to its initial loading from the server? Should I stop listening by manually calling stop() after the initial loading to release resources?
Another question:
if a parentContainer (for example the root mainUI container) fetches a collection inside a createContainer() call and wait for it to be loaded before rendering the children, can the children access its data just by importing the collection in the file and call find().fetch() ? Example, the parent container fetches all products, and one of the child wants to fetch a speficic product by productId… If he imports the products collection and call products.findOne({productId}) will the product already be available or he needs to receive it from the parent as props?
I apologize again for the length and messiness of the question, I have the feeling I am grasping the generic concept but I am getting confused in the practical details. Good karma and kudos to whoever can makes sense of my confusion and give me a enlightening explanation.
Cheers,