Store
Reading State

Accessing State

Davstack Store provides two main methods for accessing state: get and use.

It is important to understand how to use these methods in order to optimize performance and avoid unnecessary re-renders in your application.

The get Method

Use get to retrieve the current value of a state property without subscribing to changes.

This is useful eg for accessing state within callbacks or event handlers.

import { store } from '@davstack/store';
 
const countStore = store(0);
 
function onSave() {
	const count = countStore.get();
	console.log(`Saving count: ${count}`);
}

The use Method

The use method is a React hook that subscribes to changes in a specific part of the store and causes the component to re-render whenever that part of the state changes.

import { store } from '@davstack/store';
 
const countStore = store(0);
 
function Counter() {
	// will re-render whenever count changes
	const count = countStore.use();
	return <div>Count: {count}</div>;
}
⚠️

Avoid using use on the entire store or large portions of the state unless necessary, as it may lead to excessive re-renders and performance issues.

Using use with selector

You can pass a selector function as the first parameter of use to only subscribe to a subsect of that state.

This is useful for optimizing performance eg for long lists.

const activeTodo = todosStore.use((todos) => {
	return todos.find((todo) => todo.id === activeTodoId);
});

Nested Methods

You can use the get and use methods to access deeply nested state properties.

import { store } from '@davstack/store';
 
const userStore = store({
	name: 'John',
	age: 25,
	address: {
		street: '123 Main St',
		city: 'Anytown',
	},
});
const city = userStore.address.city.get();

Minimizing Re-Renders

To optimize performance and minimize unnecessary re-renders, it is best practice to use the use method on the most specific property you need within a component.

const userStore = store({
	name: 'John',
	age: 25,
	address: {
		street: '123 Main St',
		city: 'Anytown',
	},
});
 
function UserProfile() {
	const name = userStore.name.use();
	return <div>Name: {name}</div>;
}

In this example, the UserProfile component only subscribes to changes in the name property. Changes to other properties like age or address will not trigger a re-render of this component.

Computed Properties

Computed properties, defined using the computed method, can also be accessed using get and use.

const fullName = userStore.fullName.get();
const fullName = userStore.fullName.use();

Example computed values with read/write

const countStore = store({ count: 0 })
	.computed((store) => ({
		doubled: {
			// optional input here
			read: () => store.count.use() * 2,
			write: (value: number) => store.count.set(value / 2),
		},
	}))
	.actions((store) => ({
		increment() {
			store.count.set(store.count.get() + 1);
		},
		decrement() {
			store.count.set(store.count.get() - 1);
		},
	}));

Note: inputs are optional for both read/write and strongly typed.