How to integrate Mobx State Tree with Vue JS? - vue.js

I am building application on Vue and want to use Mobx State Tree as a store management library. I trying and finally made something working, but seems to it isn't work properly.
First, I have Changer component that change store via action. Works perfectly.
Second, I have Test component that tryes to react on store changes via passed props. Works fine only if I return prop via method.
Third, I have BlindTest component that tryes to react on store changes via this.$store itself and via state prop. Works fine only if I provide immutable snapshot as a state via function.
This is incorrect and strange behavior. Components updates only if props was changed, not if state was changed. Why?
Also I used mobx-vue library from official mobxjs repository for bindings between mobx and vue.
There is sandbox with demo application: https://codesandbox.io/embed/vue-template-ouq7r
Is there any way to connect MST and Vue properly?

You can use the official library: https://github.com/mobxjs/mobx-vue

Related

Implement onscreen console log component in Vue.js app

I'm building a Vue.js app that will be run on devices where I don't have access to a dev tools console, such as a game console. I've created a vue DebugPanel component that contains several tabs, one of them being a "log" to write to.
The UI is mostly working as I expect, but now I need to actually take what's in the console and have it output to the element in the component.
I'd like to use this solution of hijacking the consol.log function. This solution works great in a non-vue HTML page, but I'm having trouble with the best way to incorporate it into a Vue.js app.
The issue I'm having is that each tab section on my DebugPanel is hidden/shown based on a v-if attribute. The log element is only in the DOM when its tab element shown. So a call to document.getElementById errors.
Any thoughts on how to implement this in Vue.js?
You can just use Vuex store to pass data through all the app. And i think it would be better to use it in your app for global data.

How to share state between StencilJS components

I would like to share state between my StencilJS components. So I checked out the Redux implementation which they promote on their API site. It does something like
#Prop({ context: "store" }) store: Store;
But now I just red the BREAKING_CHANGES, which described that using context is deprecated. I actually liked using context but if this is deprecated, how can I share state between my components. I'm not really looking forward to pass everything from parent to child to etc.
The context API, even though deprecated, will still work, at least until the #stencil/redux package has been updated.
If you're looking for a simple alternative for global state, you should have a look at #stencil/store (https://github.com/manucorporat/stencil-store/tree/master/packages/stencil-store). It allows you to create a store with createStore(initalState) and returns a state reference which you can just import and reference in your component. When the store's state changes, the library will take care of triggering an update of your component.

Prevent loss of state when unmounting view

My app uses a react-navigation DrawerNavigator component to allow the user to navigate through various screens within the app.
My react-native-maps MapView component is nested inside a screen accessible via the DrawerNavigator.
The problem I am finding is that if you navigate to another page in the app, and then navigate back to the map page, the whole map has to reload and previous markers/map configuration is lost.
Is there a way that I can prevent the screen from unmounting when navigating away, or another way of stopping the whole map from resetting? I won't post code below because I believe the issue to be more theory based as opposed to fixing a code bug.
You need to persist the state when the component is unmounted. You need a state management library.
I know of two state management libraries.
RxJS is the recommended library for use with Angular. Even though it is not an developed by Angular, it is still installed by default if you use the Angular CLI to bootstrap a project. This library is incredibly powerful, especially with handling asynchronous data flows, and it fits in really well with the angular DI system. My understanding is that you create singleton services to manage particular parts of your global state. You could have many RxJS services for different parts of your app. Your components can then tap into these services and get state information from them. There are libraries which help you integrate RxJS with react components but I cannot attest to their value.
Redux is the canonical way to manage global and persisted state in React. It differs from RxJS in many ways. First, you have only one redux store in your whole app and it contains the entire global state. Second, Redux is modeled on Flux and setting up the various 'players' for the first time can be a very involved process (but once you get it it's easy). I highly recommend making use of the combineReducers function to simplify getting set up. Third, redux does not manage async data straight out of the box, you will need to reach for redux-thunkif you have async data flows.
Redux is still my go-to for global and persisted state in react because of how it integrates. There is a library called react-redux which integrates the two libraries really well. It provides you with a function called connect. The connect function accesses your global state and passes it into your components as a prop.
You wrap your entire app in a store provider line so
export default () => {
<Provider store={store}>
<App />
</Provider>
Then your individual components can access state using connect. connect accepts a function which extracts parts of your state for you. The function could look like this.
const mapStateToProps = state => {
return {
stateVariable: state.variable
}
Now you know your component will receive a prop called stateVariable which is the value of variable in your global store / state. So you can write your component to accept this prop
class Component extends React.Component {
render() {
var { stateVariable} = this.props;
return (
<View>
<Text>{stateVariable}</Text>
</View>
)
}
Then you call connect on your component with the mapStateToProps function and hey presto
const ConnectedComponent = connect(mapStateToProps)(Component)
export { ConnectedComponent as Component }
You see how this injects the props as if you had written
<Component stateVariable={state.variable} />
In this way it is a solution to prop-drilling
In addition, you can use redux-persist to persist state between sessions, not just mounting/unmounting components. This library accesses localStorage on web or asyncStorage on native.
When you call connect on a component is automatically passes in a prop called dispatch. Dispatch is a function which is used to dispatch actions which make edits to your local store. as I said the system requires some setting up - you must create constants, actions-creators, and reducers to manage these action dispatches. If you watch the first 8 videos of this course you will be well on your way https://egghead.io/courses/getting-started-with-redux
At this moment in time my recommendation is to use Redux with React.

how to use whyrun Mobx feature with react native?

I started using Mobx as state management for my react native app.
I noticed that few components render method is being called more than once. I understand its because one of the observable is modified or computed value is used. Mobx documentation mentions whyrun method to get a hint of why a particular method was run when the observable state is modified. However I did not find any reference to how to use it in react-native to find why the component render was triggered?
Did anyone use whyrun feature in react-native with Mobx?
You can import whyRun with import { whyRun } from 'mobx' and use it like you would use in a normal web project. Here are all the exports from MobX that shows the whyRun export:
MobX Exports
Hope that helps!

Differences between vue instance and vue component?

I'm new to vue js and have some questions when learning it.
I'm now a little confused about the relationship between its instance and component. As far as I learned, every app build by vue should only have one instance and one instance only, it can have as many components as you like if needed. But recently I've seen a demo, and in that demo it has more than one instance.
So my question is, is that ok to have multiple intances in one app( the demo code works fine, but is that the correct way)? What's the best practice to use instance and component in vue app?
It's ok to have two instances in the same project, however, you probably don't want to do that.
A good scenario is to have one main instance to control your app, specially if you are creating a Single Page Application (SPA). Then use as many components as you want.
Components are a great way to reuse code and keep it organized, and, with Vue.js, is very easy to communicate between your components and your "main" Vue instance.
It depends very much on your situation.
I work on a large web project which is not an SPA. We have a Vue instance for each "silo" of the application. We are slowly transitioning an older project from a mostly jQuery frontend so it's possible that as it evolves We'll be able to condense down to a single Vue instance but we're having no trouble with multiple instances. The ease of using Vue in existing projects was one of the biggest deciding factors in choosing it over another library such as react.
I have taken a different approach with green development, one instance and many components.
There are something in common, and some difference between Vue instance and Vue component.
From Vue docs:
all Vue components are also Vue instances, and so accept the same options object (except for a few root-specific options).
The root Vue instances accept properties like el, router, the Vue components cannot.
The data property in root Vue instances is an object, but in Vue components must be a function.
The design target is different:
A root Vue instance is a Vue application launcher, Vue component is an extension of the Vue instance.
Vue components can create elements to be reused in many places. This is Vue characteristic of componentization mainly reflect point.
Vue instance can associated with and manipulate an element which is already exist.
Vue component more suitable for create new element and reuse it at anywhere.
Think of a Vue Component as a blueprint or set of rules on how to create something that can be inserted into the DOM that the user can interact with.
So when you create a Vue file you are going to define exactly one component with a set of rules that tells Vue how to display stuff on the screen and tells a user how to interact with it.
On the other hand is a Vue instance, its an instance of a Vue component, it represents something that has been inserted into the DOM and is something that a user can interact with.
If you have a background in Object-Oriented Programming, think of a Vue Component as being like a class and a Vue instance as an instance of that class.
What has not been mentioned in previous answers that I will cover in regards to the difference between Vue instance and Vue component is how we define the data property that we are working with.
If we are working with a Vue instance, then we can define the data property as an object or a function that returns an object like so:
With a Vue Component that data property must be a function that returns an object.
So for example this is a Vue component:
export default {
name: "App",
components: {
SearchBar,
VideoList
},
And if we want to make use of data inside of that Vue component, we have to make a function that returns an object.
Vue components extends Vue instances
but Vue instances accept properties like el, router, the Vue components cannot.
best practice:
one Vue instance
many Vue component