I have created several components (tables, selects, etc) and all use the same methods to get API information.
The purpose is to use these components on different pages of the application and as such, so that one can use the same component (eg table) regardless of the information it receives, I have created a number of methods to allow this.
However, to apply these methods to all components requesting the API, you would have to repeat a lot of code, and as such the goal is to create these methods globally.
After a search I found three ways to do it, with Plugins, Mixins and Vuex. However I do not know what is the most ideal way to do this.
Any suggestion?
Go with Vuex.
Create a centralized store where your components interact with its data using getters, actions and mutations, and the store knows how to interact with the API.
For example, your table component can be dumb, and just expect a :data=someData that the component that initializes the table passes to it, then it just renders whatever was passed. This someData can be mapped to a Vuex getter (or directly to an item in the store state) in the parent component.
When your component needs to have something submitted to the API, it can trigger an event the parent will pick up and call the appropriate action or mutation on the store, the store will know what to call in the API to do this action. So, even your parent isn't completely aware on how the API works, just your abstraction of if, represented by your Vuex store.
I have created a very simple todos application last week for another question here, feel free to have a look, uses Vue, Vuex and saves the data to Firebase. It also doesn't implement REST as it could, but it isn't too hard to change the store to use the proper REST methods get, post, put, delete etc.
All the relevant code of this application in in App.vue and store.js, with one line in main.js just to add the store to the Vue instance.
Vuex will help with shared/own components state. If your problem is how to manage shared API call Vuex persi won't tackle that problem directly. It will help you once you get that data accessible to your components.
That said, you can create a module to do the API call and retrieve data, say:
http.js
export const getUser = async id => {
const response = await fetch(`/user/${id}`)
return await response.json()
}
export const getContent = async id => {
const response = await fetch(`/content/${id}`)
return await response.json()
}
This is a solution that will help you both with or without Vuex, now you can call those methods from anywhere.
Related
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.
I'm starting to learn about vuex. I have the question should I set this data from the Store or should I load it on the component?
For example, In my app, I load all users (firebase) from a Store Action and read it from the Getters, but when it comes to load one user data, should I fetch it from the state and then to the component or from the component itself?
I just want to make sure to make my life easier when updating or adding a new feature on the app.
Your store should be your only source of truth for global state.
This means that any component that read data should read from the store. This ensures consistency. Of course each component may need some local data, that it gets using other means and can alter the data that it gets from the store, but it should read from there.
Now you only have a dilemma regarding who should write to the store (using mutations and actions). This depends heavily on your use cases. It is perfectly acceptable to write from the components itself.
There are use cases where populating some data from outside any component makes sense. Probably the most common case is auth credentials. It is easier and cleaner to populate auth credentials before mounting the app for instance so you have one choke point for dealing with authed/unauthed users.
Bottom line is, writing to the store depends on your use case and there's no silver bullet here.
In my vue application I have X, Y, Z components, each component need to have users data from vuex.
Each component display another data but it based on the users data. this is mean the component can't be loaded unless the users data is resolved.
So I need from the X/Y/Z component to send a action to load the users data. and each component is waiting for the data using (await insertToStore, insertToStore is just my function that dispatch an action and mutate the store and after that the promise is resolved).
the problem is of course I gets duplicate http calls to the api.
I need each component to be a "blackbox". each responsible to gets the data regardless another components.
So be able to send data via the parent it is miss the purpose of be "black box".
And I need a solution to call the data but if the data is already fetching then wait until it's done. and when its done then each subscriber to this data will gets the data.
I think to use rxjs but I looking for a vue solution or JavaScript solution because I don't want to insert rxjs if I don't have to.
You can use events for this.
So the idea is to create a parent component which will get information about users. And after it will receive this data, it will $emit the event.
In general, you'd have situation when all of your components will wait until the parent's "Hey, guys. I've just received the data here. Feel free to render. :)".
Try getters in Vuex: https://vuex.vuejs.org/guide/getters.html
And in main/parent component use dispatch to get user data.
I have a pretty basic vue/vuex project, and I load a list of categories from my database via a Http get request. Before incorporating Vuex into my project, I was just making the HTTP get right when I create my main component that uses the data. Now, in Vuex I have my getters and mutations and actions, but, what I don't clearly get is the proper way (or place) with Vuex to do that get and fill the state object categories. I could still run the Get in my component create and then fill the Vuex state through the actions, but that seems kind of backwards. Hoping someone can point me to the proper "best practice" way to do this.
Instead of running the request from your component and filling the state with the results, you can dispatch an action which makes the request and commits the mutation with the results. If you want it to happen immediately, dispatch the actions from the create method of the root vue node.
I'm newbie in react and redux.
Question: what is the best way to implement "datasource" (similar to kendo-ui datasource) in redux?
I've tried to store all of my widgets datasources in one place (i've created datasource reducer) and "bind" datasources to it's widgets (like table widget, listview, combobox etc). Datasources must have it's own api (like addFilter, addSort, getFiltered etc) and also store applied filters and data too.
I want to store all of datasources in redux store (that's why i need to create datasource and dispatch it's creation before widget is created).
The problem is when i create react-redux connector to my "smart" widget's container-component i need to send my datasource with props but at this moment datasource is not created.
If i send dummy initial datasource (without dispatch it's creation and data filling) and then dispatch it and fill data to it on componentDidMount - my widget's render function called twice
I think i need some kind of "wrapper" function but at now i have no idea how to do that.
Maybe there is some examples of how to implement "datasources functionality"?
Just let render be called twice. It's the right thing to do in react-land.
Stuff has changed. Let's re-render and let the diff-engine do it's thing.
You need to fully accept the action->reducer->smart-component dichotomy.
Data source seems like a wrong abstraction in Redux. You don't want to conflate retrieving the state from the state tree (selectors), fetching it (action creators) and describing mutations (reducers). If you'd rather have a data source-like abstraction, you shouldn't need Redux.