Multiple observers
If you have a large-scale application, or you want to manage different the state of each part of your app separately, you can create multiple instances of the Observer class for this purpose.
If you to make instance of the Observer
class, you must import the Observer
from rosma
and create an instance of it using the new
keyword.
import { Observer } from 'rosma';
const myObserver = new Observer();
Note that you can pass the initial values of the state to the constructor of the observer class.
import { Observer } from 'rosma';
const myObserver = new Observer({ foo: 'bar' });
console.log(myObserver.state.foo); //"bar"
Also, in order for the useObserver hook to use your personal observer, you can send your own observer to it.
import { Observer, useObserver } from 'rosma';
const myObserver = new Observer({
random: 'Click Generate to generate random number',
});
function App() {
const { random, setRandom } = useObserver(myObserver);
return (
<>
<p>{random}</p>
<button onClick={generate}>Generate</button>
</>
);
function generate() {
setRandom(Math.random() * 1000);
}
}
Click Generate to generate random number
Custom useObserver hook
In order to not repeat passing the observer
to the useObserver
hook throughout your app, you can export your personal hook once and import it everywhere in the app, as in the example below.
import { Observer, useObserver } from 'rosma';
const initialUIState = { mustShowSidebar: true };
const initialAuthState = { user: undefined, token: undefined };
const initialDataState = { posts: [], users: [] };
export const UIObserver = new Observer(initialUIState);
export const authObserver = new Observer(initialAuthState);
export const dataObserver = new Observer(initialDataState);
export function useUIObserver() {
return useObserver(UIObserver);
}
export function useAuthObserver() {
return useObserver(authObserver);
}
export function useDataObserver() {
return useObserver(dataObserver);
}
This example is demonstrating how to create and export multiple instances of the Observer
class with different initial states, using the new
keyword. Three instances of the observer
are created with the names UIObserver
, authObserver
, and dataObserver
. Each instance has a different initial state, which is defined using objects.
In addition to creating the observers, we exports three functions, useUIObserver()
, useAuthObserver()
, and useDataObserver()
, which use the useObserver
hook to provide access to the respective observers throughout the application.
This approach can help in managing the state of different parts of an application separately. By having separate observers, you can easily modify the state of a particular part of the app without affecting the state of the other parts.
Separating observers
To keep your code clean, it is better to keep the observers for each part of your app in a separate file. For example, the above code can be placed in three separate files as shown below:
UI part
src/observers/ui/observer.ts
import { Observer, useObserver } from 'rosma';
const initialUIState = { mustShowSidebar: true };
export const UIObserver = new Observer(initialUIState);
export function useUIObserver() {
return useObserver(UIObserver);
}
src/observers/ui/actions.ts
import { UIObserver } from './observer';
export function toggleSidebar() {
UIObserver.set({ mustShowSidebar: !UIObserver.state.mustShowSidebar });
}
Auth part
src/observers/auth/observer.ts
import { Observer, useObserver } from 'rosma';
const initialAuthState = { user: undefined, token: undefined };
export const authObserver = new Observer(initialAuthState);
export function useAuthObserver() {
return useObserver(authObserver);
}
src/observers/auth/actions.ts
import { authObserver } from './observer';
export function login({ username, password }) {
// logics for login
authObserver.set({ user, token });
}
export function logout() {
// logics for logout
authObserver.set({ user: undefined, token: undefined });
}
Data part
src/observers/data/observer.ts
import { Observer, useObserver } from 'rosma';
const initialDataState = { posts: [], users: [] };
export const dataObserver = new Observer(initialDataState);
export function useDataObserver() {
return useObserver(dataObserver);
}
src/observers/data/actions.ts
import { dataObserver } from './observer';
export function getPosts() {
// logics for getting posts
dataObserver.set({ posts });
}
export function getUsers() {
// logics for getting users
dataObserver.set({ users });
}
Note: This example is given in order to provide a concept of how to manage the state in an app. The parts provided above are for illustrative purposes. For instance, in the data
section, it is advisable to use more specialized libraries for fetch and caching data, like react-query
.
Keywords: React, rosma, observer, useObserver, multiple observers, custom useObserver
Previous: Observer class