For example I have simple TODO app.
Task represented by Task component. As storage I use Vuex.
For each task I store structure like
{
id: 999,
label: 'My super task',
done: true
}
Questions is what I have to pass to the component as property - only id (and then get other data from store) or the whole data array?
Passing whole data will make the your Task component independent from store.
Passing only ids of tasks will make your Task component dependent on store for tasks data.
Since Task is representing a single card, I think making it dependent on the store will increase the calls to the store since n number of tasks will call store for data.
It is better to get the data from store once and then enumerating the data using v-for directive and passing whole task object to your Task component.
So you can pass it however you like. Keep in mind, if you're using Vuex, you don't need to pass anything as a prop since you have a central source of truth. Instead, you can call straight from the state or use a getter.
Inside your child component, you can refer to the store with $store in the template and this.$store in the script.
For example:
const myTasks = this.$store.state.tasks (if tasks is an array or collection of some sort)
const myTask = this.$store.state.tasks[0]
Then you have myTask.id, myTask.label, etc.
If you need a more specific example, please post more code and let me know.
Related
For vue data, for every tutorials I have seen, it seems that data variables first defined as return value when creating vue instance like below:
app = createApp({
data() {
return {
someData: null,
}
},
}
I wonder if this practice is some way necessary or if it is just a convention, because I could simply define new data like this.someData2 in mounted or methods and it seems to work pretty much the same way.
I could simply define new data like this.someData2 in mounted or methods and it seems to work pretty much the same way ?
Answer is Yes, You can add a new property directly to this without including it in data. However, properties added this way will not be able to trigger reactive updates.
But we use the data option to declare reactive state of a component. The option value should be a function that returns an object. Vue will call the function when creating a new component instance, and wrap the returned object in its reactivity system.
Please do through this official documentation of Reactivity Fundamentals for better understanding.
the data option must be an function so every vue instance can maintain a separate copy of the return object,so it won't infect other instance
Mobx and Redux will normally not persist any data. They will maintain a temporary global state while the app is running.
I know there are redux-persist and mobx-persist packages within both communities. But unfortunately these persisting solutions do not seem good at all. They only stringify or serialize a global state tree and persist it using some sort of key-value storage. Right?
The problem:
When such an app is open again, the stringified store will be parsed and structured back to its original data structure (JSON, for instance) and then fully loaded into the RAM memory. Am I right?
If yes, this is a problem. It is not good to always have a full "database" aka "global state" loaded in-memory. It will probably never be faster to filter data within a long array in my global state... compared to querying a table on SQLite, right?
I have been looking for some repository-like solution for persisting global state for either redux or mobx. I am yarning for some solution for persisting and querying data on some well-known mobile database like SQLite or others.
Any answers will be very much appreciated.
Indeed you can use repository pattern.
On your repository, you may have a save method.
save(group: GroupLocalStorageModel): Promise<boolean> {
let created;
this._localStorage.write(() => {
created = this._localStorage.create<GroupLocalStorageModel>("Group", group);
});
return Promise.resolve(true);
}
This method will literally save your entity to some local storage you set. In the example above, we are saving a group object to a Group collection which are like tables. We are using realm which is no-sql.
Once you have your repository, if you are using either redux or mobx, you will probably call your save method on your action. Both redux and mobx work with actions, right?
export const GroupStoreModel = types
.model("GroupStore")
.props({
groups: types.optional(types.array(GroupModel), []),
})
.extend(withEnvironment)
.actions((self) => {
return ({
_addGroupToStore(group: GroupLocalStorageModel) {
self.groups.push(group)
},
_deleteAllFromStore() {
self.groups.clear()
},
_addGroupsToStoreBatch: (groups: GroupLocalStorageModel[]) => {
self.groups.concat(groups);
},
})
})
/* Async actions */
.actions((self) => {
let groupRepository = self.environment.groupRepository;
return ({
addGroup(group: GroupLocalStorageModel) {
groupRepository.save(group).then(result => self._addGroupToStore(group))
},
getAllGroupsPaginated(page: number) {
groupRepository.getAllPaginated(page).then(groups => self._addGroupsToStoreBatch(groups));
},
deleteAll() {
groupRepository.deleteAll();
self._deleteAllFromStore();
}
})
})
In this example, we are using mobx-state-tree. And this addGroup action will update firstly our database, and then update also the global state.
We still want to use our global state so our views will be re-rendered automatically according to either connect for redux or observable for mobx.
See more informations here on the repository:
https://github.com/Hadajung/poc-react-native-database-example
AFAIK, there are two options for using sqlite with redux persist.
redux-persist-sqlite-storage: By maintainer's own word
By default redux-persist uses AsyncStorage as storage engine in react-native. This is a drop-in replacemet of AsyncStorage.
The library is inspired by react-native-sqlite-storage.
Please, remember, to use this, you need to install an additional package installed react-native-sqlite-storage
redux-persist-sqlite: By maintainer's own word
A redux-persist storage adapter that writes to sqlite.
This is adapted from https://github.com/prsn/redux-persist-sqlite-storage, but uses Node.js sqlite3 rather than react-native.
Great for Electron apps that are backed by Redux.
UPDATE: react-native-mmkv : This is developed by WeChat. As it says in its about section
An extremely fast key/value storage library for React Native. ~30x faster than AsyncStorage!
I'm not really sure what you need but if I understood you correctly you need to persist large amounts of data, and also to load that same data, but only in batches.
I believe that this kind of problem can be solved with a repository pattern and SOLID design principles.
You will need:
store class (mobx store) that holds your business logic.
repository class which is responsible for retrieving and persisting data.
The store gets the repository injected into it via the constructor.
Then when you call the initialize method on your store, it talks to the repository and retrieves the initial data. Now, initial data can be only a subset of all the data that is persisted. And you can implement some kind of paging on the store and repository, to retrieve data in batches as needed. Later you can call other methods to load and save additional data as needed.
pseudo code:
class Repository(){
initialize()// load the first batch
load(next 10 models)
save(data)
}
class Store{
constructor(repository)
initialize(){
repository.initialize()
}
load(){
repository.load()
}
save(){
repository.save()
}
}
Now your application data shouldn't be one giant object, rather it should consist of multiple stores, where each store is responsible for a part of the data. For example, you would have one store and repository for handling todos and another pair that handles address book contacts etc.
Addendum:
The reason the repository is injected into the store is so you could easily swap it for some other implementation (the store doesn't care how the data is persisted and retrieved) and also, unit testing is very easy.
You could also have a root store that would hold all other stores, so in essence you have your complete state in one place. So if you call serialize on the root store, it serializes all stores and returns one big object.
I think the best solution would be bloc hydrated or cubit hydrated package from flutter_bloc.
https://pub.dev/packages/hydrated_bloc
In background it uses Hive DB, very performant DB, and only keys are stored in memmory so it should not add huge bloat to the app like SQLite.
If you could make all you APP logic in blocks/cubits, then extra DB calls would be irelevant.
I am new to react/redux. I am trying to figure out how all the pieces in redux interact. The one thing giving me trouble is understanding the relation between actions and reducers,store.
It's pretty simple when you think about it:
Store - Is what holds all the data your application uses.
Reducer - is what manipulates that data when it recieves an action.
Action - is what tells reducer to manipulate the store data, it carries the name and (not required) some data.
Reducer is usually in a format of a switch statement, that switches between all possible Actions (Cases) and then manipulates the Store data based on action. When a reducer data changes within the redux, the properties in your components are changed and then the re-render ocurrs.
Store -> A Globalized state
Action -> What you wanna do, eg: event click
Reducer -> Describes how your action transfers state into the next state.
It checks which action took place and based on the action it updates the store.
Dispatch -> Way how we execute the action. eg: Dispatch the action to the reducer. Then reducer will check what to do and the store gets updated.
Store
An Object that holds the applications state data
Reducer
A function that returns some state data. Is triggered by an action type
Action
An object that tells the reducer how to change the state. It must contain a type property. It can optionally contain a payload property
The actions, reducers and stores are the three building blocks of redux.
Actions: Actions are the only source of information for the store. Actions have a type field that tells what kind of action to perform and all other fields contain information or data. And there is one other term called Action Creators, these are the function that creates actions. So actions are the information (Objects) and action creator are functions that return these actions.
Reducers: As we already know, actions only tell what to do, but they don’t tell how to do, so reducers are the pure functions that take the current state and action and return the new state and tell the store how to do.
Store: The store is the object which holds the state of the application.
I found this link to be particularly helpful - https://www.geeksforgeeks.org/introduction-to-redux-action-reducers-and-store/
Imagine a situation where you want your class based components to share data among each other. They may even bring changes to the data. One may provide data to others in the form of props. But it very difficult to keep track of the name of the props and the structure of data.
The Store actually simplifies this stuff. You set up your application architecture in such a way that the components will get their data from the supply what is known as the Store. Actually, the mechanism is so smart the component will re-render itself when the data changes since the components are all ears.
And Actions are nothing but the carriers of data from your application to the store.
And it is very difficult to articulate the concept of reducers. You may imagine a real store where one puts different stuff for future use. The store is of no use when the stuff is put haphazardly. One may spend hours inside but may not find anything. The Reducers in simple terms manage the way data is kept in store provided by the actions.
according to redux documents:
store: The whole global state of your app is stored in an object called store.
dispatcher: To change something in the state, you need to dispatch an action. (and that is what dispatcher does)
action: An action is a plain JavaScript object that describes the kind of change to make (as dictated by action.type) to the store and the relevant payload required for that change.
reducer: to tie state and actions together, we write a function
called a reducer. it’s just a (pure) function that takes state and action as arguments and returns the next state of the app.
for a deeper understanding look at the diagram in this link.
Actions: Actions are a plain JavaScript object that contains information. Actions are the only source of information for the store. Actions have a type field that tells what kind of action to perform and all other fields contain information or data.
Example :
function addTask(task) {
return {
type: 'ADD_TODO',
task: task
}
}
Reducers: As we already know, actions only tell what to do, but they don’t tell how to do, so reducers are the pure functions that take the current state and action and return the new state and tell the store how to do.
Example:
function task(tasks = [], action) {
if (action.type === 'ADD_TODO') {
return [...tasks, action.task];
} else if (action.type === 'REMOVE_TODO') {
return tasks.filter(task => task !== action.task);
}
return tasks;
}
Store: The store is the object which holds the state of the application.
ref: https://www.geeksforgeeks.org/introduction-to-redux-action-reducers-and-store/
In my Vue.js project, I have many components, in some of them, those component will all use a fetched data list, called it server_list.
I don't want to fetch it in every component who used it.
so, how can I optimize this?
only in one place to fetch it?
such as, In component_foo, I will invoke fetch_server_list(), in component_bar, I will invoke fetch_server_list() too.
How can I deal with in multi places to fetch server list data?
What's your best way to deal with this?
There are many ways to do that.
Props
Props lets you pass data to child component.
Provide/Inject
Providers lets you pass data nested, more than one level.
Vuex
Vuex stores lets you cache your data in $store object to use later, wherever you want.
I currently have a Vue.js 2 SPA using Vuex for inter-component communication and Vuex-persisted state to persist my shared state.
However, I want to persist a component's local private data.
I tried the package vue-persist and it persists the component data fine, however, the variables are not namespaced and therefore shared between all component instances. I want to persist each component's data separately.
Does anyone know how I can achieve these 2 things in my Vue.js 2.x app?
1) Persistence of my local data (so it survives a browser refresh).
2) The persisted data is not shared with other components (perhaps name-spaced for each component instance?).
Thanks!
I'm not familiar with vue-persist, but it looks like you can pass a store name as the second argument to $persist. Choose a unique store name for the component instance (this will vary depending on the component).
e.g.
created() {
this.$persist(['foo'], 'my-comp:' + this.id);
}