Skip to content

Batched updates for shared slicesΒ #208

@zaesur

Description

@zaesur

In the official Zustand docs, they show an example of "shared" slices, where you can access other slices and create composite actions.

const createSharedSlice: StateCreator<
  BearSlice & FishSlice,
  [],
  [],
  SharedSlice
> = (set, get) => ({
  addBoth: () => {
    // you can reuse previous methods
    get().addBear()
    get().addFish()
    // or do them from scratch
    // set((state) => ({ bears: state.bears + 1, fishes: state.fishes + 1 })
  },
  getBoth: () => get().bears + get().fishes,
})

While the Zundo docs do show an example of the slices pattern, it does not mention the shared slices functionality. Of course, if state is set twice, this will push two states on the undo stack, rather than just one.

What would be the ideal way to 'batch' updates together, such that they are grouped as a single update? It doesn't seem possible to use the pause/resume functionality for this, as this is on the slice level, before the store is created.

I have created a playground which illustrates the problem.

Once way of working around the problem has been to create a leading debounce function (one that only executes the first call within a given time window), and using that with handleSet.

type AnyFunction = (...args: any[]) => any;

function debounce<T extends AnyFunction>(func: T, wait: number): (...args: Parameters<T>) => void {
	let timeoutId: ReturnType<typeof setTimeout> | undefined;
	let hasExecuted = false;

	return function (...args: Parameters<T>) {
		if (!hasExecuted) {
			func(...args);
			hasExecuted = true;
		}

		clearTimeout(timeoutId);
		timeoutId = setTimeout(() => {
			hasExecuted = false;
		}, wait);
	};
}

This works, but it doesn't seem ideal - are there any other solutions to this problem?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions