How to pass data from a VueJS component to main.js? - javascript

Is it possible to send data defined in a component in the data() method to the main.js file (or where the Vue instance is defined)? I thought I could use vueX to do the following but have no idea as how to approach it even after understanding computed props, getters and mutations:
Data in Component -> Store -> Main.js
EDIT: HOW DO I SET DATA IN THE VUEX STORE FROM THE COMP?
Imagine the store has a property called currentList, whose values need to be fed in from a list in Component1.vue. How would I send that list to the VueX Store?

If you want to pass data from your component to the Vuex $store, you should use Mutations (or actions, if the data comes into your component asynchronously).
Assuming your mutation has already been defined in the store (and the store has been set up correctly), you can call it from your component as follows:
this.$store.commit("YOUR_MUTATION", "data")
I do recommend the vue-tools in your browser to keep track of what's in your store.

I know no Vue, but I believe I understood what you're looking for.
What you're trying to achieve here, in every other front-end framework, can be called like: "component to parent communication".
You can have a 4th level nested component and you want to pass some data to the Main.js (that I suppose, in Vue, it's still a component, precisely the root one)
As I see, you can use $emit: https://forum.vuejs.org/t/passing-data-back-to-parent/1201
In React (and you can do this in Vue too, but you should choose the vue style solution) you would use a callback function: the parent pass to the child a function that the child can call to set a certain property inside the parent comp.
Another common option nowadays, that avoids completely this kind of communication, is the use of a state management lib like Redux. In that every component can access a global store (that is like a global variable) and after the 4th level component set a property in this global store, the main.js can read it.

Related

Where should my `fetch` request be placed in my React app without having to pass data between the child and parent component?

I'm working on a project right now, where I have App.jsx, and my other components inputComponent and articleComponent. App.jsx contains both my inputComponent and my articleComponent. However, I've written the fetch request to be within inputComponent.
In this case, my articleComponent relies heavily on the data retrieved from the fetch request, and so I'm thinking, a possible solution would be to move the fetch from inputComponent to articleComponent. Another one was to use callbacks to pass data from the child component to the parent component. However, based on some answers I've read here and online, it seems that this method of passing data from the child component to the parent is a React anti-pattern as well.
I also think that the fetch call ideally shouldn't be on App.jsx, but feel free to correct me if I'm wrong.
Ideally, what I need is for the data retrieved from the fetch call (which comes from user input submission in inputComponent) to be able to be passed in as props to the ArticleComponent so that I can render the articles with the proper data after fetching it from my server. What would be the "React" way of doing it, and also the best way in general?
As #misternobody said, the 'normal' way is to pass data down to children as props and yes, if a parent's state change - it re-renders all of its children (that's the idea behind React).
So you would pass your input from inputComponent up to App (with the use of a callback passed as a prop), fetch inside your App, then pass the response down to ArticleComponent
If for some reason you want to dodge the rendering of App component in this process, you'd have to use ie. Redux and NOT connect App to the store. Then, if you'd properly map store's state and diapatch to props in your 'child' components, it should work as you intended without bothering App.
Normally the properties you want in all children sit in the parent class.
I would write the fetch right there, and pass it to the children as props.

Updating data on a Vue component shared between 2 routes

So basically, i have declared 2 different routes and set them to use the same component.
How do i go about updating the data (different API requests based on route) in this component.
I managed to make it work by calling a method this.updateData per say and calling this method on created lifecycle hook and also calling it on watching the $route.path property, and it works but it seems a dirty way to make it work to me, and i might be missing something.
Edit: Im using just Vue js for Simple Page Application, no other frameworks nothing fancy.
For anyone running to the same problem, vue.js tries to reuse components instances as much as it can so basically unless you have a key unique attribute on the component it will point to the same component instance.
So to have a different instance for everytime you use that component add a key attribute which has to be unique. e.g.
<router-view v-bind:key="$router.path" />
In this case it will use the path as a key so that for each route you use a shared component it will create a new instance and you can access the created() lifecycle hook on each one.

VueJS: change global state through chain of recursive components

I use recursive component to render nested array in Vue. Also I need to make possible to check any leaf of these tree, render every node as true/false/indeterminate (if some leafs are selected) and store all selected values in some ‘global’ variable. What’s the right way to pass the information and store the states? I think using a reference to the “root” component is not right and creating chain of events through all nested components may be too much?
This is a perfect task for vuex.
It is the defacto store system into the vue ecosystem.
You store all of your data into that store and access and manipulate them with mutations and getters.
And you get the benefit, that everything in your Views stays synced.
Check out their amazing docu at: https://vuex.vuejs.org/en/intro.html

Sharing application store state

Im using Vue and Vuex in my application and I have some components. By the time passing I know I will probably have a few more which is gonna be a lot. So I have a problem with sharing the app state within all the components. So I'd like to know which way should I follow? Either passing the state to all the components no matter child or parent, or passing the state to a parent one that will be used in some of its child components and then passing the state to them as a property (however, I do need to import the mutations methods because props are not reactive)?
UPDATE:
Keep in mind though that if a component is going to be displayed or hidden and the conditional statement v-if is attached to the component custom tag, each time the entire component is going to be rendered again! But not if statement was only on some child tags in the component.
Thanks in advance.
What you are asking is a false dilemma. From the official documentation:
By providing the store option to the root instance, the store will be injected into all child components of the root and will be available on them as this.$store.
(emphasis mine)
Which means that sharing the store between components no matter how deep in the component tree is handled for you automatically by vue and vuex.
It's quite opinion based question, but I would say it is much better way to use Vuex since the beginning if you know that your app can be developed into large scale.
Passing states from parent to child all the way etc is not good way, so it is better to use Vuex now and you will save a lot of time changing your app in the future when you would have no other way than vuex.

Caching props in getDefaultProps an anti-pattern in React?

I am writing a complex react app and using Cortex as my central model. The philosophy with cortex is that it wraps your data and on changing the data, calls a complete re-render from the root. This works great especially when you have non hierarchical views changing state and affecting the other.
The issue that I am facing is maintaining states/props on re-render. For example I have a certain hierarchy which goes like this:
<Page>
<EditorCard>
<Editor/>
<PublishButton/>
</EditorCard>
</Page>
The EditorCard needs the JavaScript instance of the Editor in order to make changes to the Editor on clicking the PublishButton (I am using an external library inside Editor which exposes methods for editing). Hence the Editor on ComponentDidMount sets the instance as a prop on the EditorCard by calling a function passed down to it.
My issue is that when I click the PublishButton I change the value of the cortex object which causes a re-render from the root and I loose the props for that Editor (since component is already mounted ComponentDidMount is not called again).
The way I took care of this problem is by caching of getDefaultProps.
Inside EditorCard my default props are:
getDefaultProps: function() {
return {
cachedData: {},
}
},
And is saving the editor instance as this.props.cachedData.editor = editorInstance
This saves props over multiple re-renders.
Is this how getDefaultProps caching was meant to be used? On saving props over multiple re-renders am I breaking some of the core react rules with this hack? Could you suggest a better structure if so?
No, getDefaultProps is what it means to be: getting the default props in case the owner hasn't passed those to you. You could say it's a shorthand for a = this.props.bla || 'hello';.
That being said, if I'm understand your question correctly, I see three ways to solve it.
Cache that in your state instead. Props are passed by the parent and are meant to be read from, inside the child, at least in vanilla React.
Instead of putting that props passing logic in your componentDidMount, why not put it in componentDidUpdate?
ref lets you grab the instance and call its methods directly.

Categories