In Mobx can a complex component have it's own store? - mobx

I have built a complex date management component that itself is made up of many smaller components nested a few layers deep. The components at different levels need access to observables and actions that live in the root component. I am dealing with this by passing what I need through props. While this all works, the code would be much simpler and easier to follow if I could create a store in the root component, use provider, and then inject in the child components as needed. Exactly like we do when creating a store for app wide use.
So to summarize...
I want each instance of my complex date component to create it's own instance of a store. I want to then use provider and inject to pass this store instance to child components.
Before I proceed with this significant refactoring, I want to be sure that this approach will work and is sound. Is there an alternative approach that makes more sense. Am I overlooking something?
Note: Although I know code samples are useful, I'm hoping that what I am describing is straight forward enough that they are not needed in this case.

Yes, you can create stores for a component and use Provider and inject to pass them to child components. Actually that is what I do in my current project and it works well.
BTW, I think this is a big Pro of MobX compared to Redux. You do not need to keep all states in a single global store. You can create complicated components that work perfectly by themselves. It is object-oriented, which is the philosophy of React.

Related

Provide/inject or Vuex?

I have a list of cars. Each item of that list has all the information about some of the cars. Also each item is a parent component to many other components - image, price, characteristics, etc - all that info is in separate components.
The information about all those cars is stored in Vuex. Now I am trying to think of a better way to pass that information to each of the list items.
Pass all the necessary data about another car to the parent component. And then provide it to the child components.
Each child component gets the necessary information from Vuex directly.
Provide-inject is mainly used to pass data to nested components.
Vuex on the other hand, keeps the app state shared.
You need to ask yourself whether the data you need in your component is coming from a parent-parent component or the data is used in many components in different parts of the app. If you need the first, then go with the provide-inject, otherwise, pick Vuex.
Both approaches are prone to be badly implemented and potentially impact negatively on your app development and maintainability, so be very careful and learn the basics in-depth ;)

vue.js how to organize front-end data (e.g. product information)

What is the correct pattern to store e.g. static product information data within a vue2 single page application?
Previously I've used an external js file that included a JSON with product-attributed (e.g. name, weight, height etc).
I don't want to load via AJAX since the spa needs to work without a web-server.
While VueX is meant to provide to a single source of truth for dynamic data throughout your single page application, I think it's also the proper and clean way of storing static data. VueX allows you to write getters and setters (as mutations / actions), now if you simply leave those setters out of your module you'll have a centralized store module that is read-only but available in every component.
Why is that better than just using a static JSON file?
Using a JSON file will expose the entire content to every single component that uses that file. In some cases that might be what you want, but it's by far not as flexible as having multiple getters that allows you to define the exact scope of what each component should receive. Also VueX uses all observable patterns and best practices from Vue itself, so the integration of your data in for example computed properties is super easy. Due to the getters pattern you'll also be able to define any kind of filtering or sorting in one place that you can share in your entire application. While that might not be what you need right now, keep in mind your requirements may change over time and simply having the option to easily implement that later is also a good thing. Same goes for reading the data from an Endpoint instead of having it statically. Your application might not need that right now, but in case you want to do that somewhen in the future, vuex will make it super easy to transition to dynamic data without you having to change any component.
What speaks against VueX?
Not that much. While it's a little bit of overhead if you really only use it for static data, the possible scalability it offers you is worth that minor downside.

Vue Js : Passing Data among siblings

Is there any other way to pass data between 2 siblings without using event bus or parent component in vue js?
I know that it can be passed with the help of Props and event emission. It can also be passed with the help of event buses.
If it is complex you would go you Vuex is the best solution in my opinion. However, if you just want a simple way to communicate between the components, you can simply go for OO Shared State. This is just a class that maintain your data that you can access from any components just pass it though, similar to singleton concept it OOP. There is a good example how to do this in Laracast website; have a look here https://laracasts.com/series/learn-vue-2-step-by-step/episodes/24.
A general question is going to get a general answer. You need to ask yourself why your siblings need to talk to each other. Most often it's because you're not using a store. It would be a mistake to think of vue components like objects in an OO language. Vue components are fed via reactive pipes from a store, the store is not a vue component. If you're doing this correctly, you don't often need to pass stuff between vue components.

Difference between calling new Vue() from main.js V/s calling from each and every component

I have a project where I have initialized new Vue() from main.js using #app.mounted.
Thereafter I have injected all router views from each and every component into the app.
Now, what I am thinking is I should call new Vue() in each and every component instead of calling from one central main.js file.
I am asking if this approach of calling/importing Vue and initializing from each and every file is a good approach or should I stick to initialize from one central file.
It is perfectly valid to include multiple Vue instances, there is nothing wrong with that, as long as they are self-contained and and didn’t rely on other Vue instances. It’s still fine to access Vue instances after they have been initialized, because this doesn’t break the principle of loose coupling, and they can therefore still be isolated from each other.
Adding two Vue instances to the same page, which operate on different parts of the DOM. This is very useful for adding widgets to a page, eg, one Vue instance would be responsible for a form on the right hand side of the page, and another would control the navigation.
But, as it's not a big problem at a small scale, it can quickly lead to code that is very hard to maintain. Because your Vue instances would no longer be isolated from each other, it can be very hard to figure out the dependencies between them, and changing something in one Vue instance could easily break another.I just want to recommend that you stay away from this approach.
Single Vue instance bound to the whole page and do all of your logic in one component, that can get messy very fast. It all depends on what you're trying to achieve, but vuex can help keep your state in order while using multiple components.
No. There is no need to generate a new Vue instance.
Generally speaking, only single Vue instance should exist in your application.
Special Use cases that might lead you to create multiple Vue instances:
Event Bus: It requires a new Vue instance.
Mounting Vue instances on different parts of your legacy DOM. You never need this if you create Vue application from scratch.
I highly recommend you to take a look at high-quality solutions (templates) that are already made up for you and maintained by a large community, before taking decisions that has already been addressed.

What is a good pattern to access other components' states?

I encounter a situation where component A needs to know about the state of component B when A is asked to perform certain actions (for example, if edit menu is toggled, the save action on the save button should not be performed). My application is structured like a tree with nested components.
I have tried passing all the components I need into the constructor of other components. I find this quite tedious whenever I add more component to the application, I have to pass them all the way down. Furthermore, some components are instantiated under the same constructor, but they need to know about each other. I cannot pass say component A and B into each other since I need to instantiate them in order.
I have also tried using event system to signal between components. (Observer pattern ?) It seems to be more of an overkill and not intended to be used like this.
3rd thing I try is to use singleton through dependency injection. Components register themselves on init to the provider and the provider can be injected to provide access to other components.
The 3rd approach is the most effortless and it is working for me. But I google that Singleton is not a recommended approach since it is just global variable and it entangles the code. But Unity game engine seems to have the same thing ( FindComponentByTag ). What is the general practice for this ?
The standard pattern for handling things like this is MVC (Model View Controller) which usually makes use of the Observer pattern. Components (I guess that you are having GUI components in mind) should not directly access the state of other components. Instead, state should be handled by the model. The components that need to know about the state are registered as observers of the model.