Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/cdellacqua/stores.js-react-adapter

A library that provides React Hooks and components for universal-stores (observable containers of values).
https://github.com/cdellacqua/stores.js-react-adapter

react react-hooks stores

Last synced: about 1 month ago
JSON representation

A library that provides React Hooks and components for universal-stores (observable containers of values).

Awesome Lists containing this project

README

        

# @universal-stores/react-adapter

A library that provides React Hooks and components for [universal-stores](https://www.npmjs.com/package/universal-stores) (observable containers of values).

[NPM Package](https://www.npmjs.com/package/@universal-stores/react-adapter)

`npm install universal-stores @universal-stores/react-adapter`

(note that you also need `universal-stores`, as that's a peer dependency of this package).

[Documentation](./docs/README.md)

## Hooks

### useStore

`useStore` is designed after `useState`. By calling this hook you'll get a tuple where
the first element is the current value contained in the store and the second element
is a setter/updater.

As you can see in the following example, the setter accepts both a new value and
an update function.

```tsx
import {makeStore} from 'universal-stores';
import {useStore} from '@universal-stores/react-adapter';

const count$ = makeStore(0);

function Counter() {
const [count, setCount] = useStore(count$);
return (
<>

{count}


setCount((c) => c + 1)}>Increment
setCount(0)}>Reset
setCount((c) => c - 1)}>Decrement
>
);
}
```

### useReadonlyStore

`useReadonlyStore` returns the value of a store. It can be used with
both `ReadonlyStore`s and `Store`s.

```tsx
import {makeStore} from 'universal-stores';
import {useReadonlyStore} from '@universal-stores/react-adapter';

const count$ = makeStore(0);

function Counter() {
const count = useReadonlyStore(count$);
return (
<>

{count}


>
);
}
```

```tsx
import {makeReadonlyStore} from 'universal-stores';
import {useReadonlyStore} from '@universal-stores/react-adapter';

// A lazy loaded readonly store that increments its value every second.
const autoCount$ = makeReadonlyStore(undefined, (set) => {
let count = 0;
set(count);
const intervalId = setInterval(() => {
count++;
set(count);
}, 1000);
return () => clearInterval(intervalId);
});

function Counter() {
const count = useReadonlyStore(autoCount$);
return (
<>

{count}


>
);
}
```

### useReadonlyStores

`useReadonlyStores` can be used to observe multiple stores at once.
It takes an object or an array of `ReadonlyStore`s and/or `Store`s and returns an object or an array of values contained in them.

Example using an object:

```tsx
import {makeStore} from 'universal-stores';
import {useReadonlyStores} from '@universal-stores/react-adapter';

const firstNumber$ = makeStore(4);
const secondNumber$ = makeStore(2);

function Sum() {
const {first, second} = useReadonlyStores({
first: firstNumber$,
second: secondNumber$,
});
return (
<>

{first + second}


>
);
}
```

Example using an array

```tsx
import {makeStore} from 'universal-stores';
import {useReadonlyStores} from '@universal-stores/react-adapter';

const firstNumber$ = makeStore(4);
const secondNumber$ = makeStore(2);

function Sum() {
const [firstNumber, secondNumber] = useReadonlyStores([
firstNumber$,
secondNumber$,
]);
return (
<>

{firstNumber + secondNumber}


>
);
}
```

## Components

If you only need the value of a store in a specific section of your JSX, you
can use the following specialized component to optimize the Virtual DOM diffing
process. The following component will make changes affect only a subtree of your main component.

### WithStore

Similar to `useStore`, it takes a `Store` and a render prop as its children:

```tsx
import {makeStore} from 'universal-stores';
import {WithStore} from '@universal-stores/react-adapter';

const count$ = makeStore(0);

function Counter() {
return (

{(count, setCount) => (
<>

Counter: {count}


setCount((c) => c + 1)}>Increment
setCount(0)}>Reset
setCount((c) => c - 1)}>Decrement
>
)}

);
}
```

### WithReadonlyStore

Similar to `useReadonlyStore`, it takes a `ReadonlyStore` (or a `Store`) and a render prop as its children:

```tsx
import {makeStore} from 'universal-stores';
import {WithReadonlyStore} from '@universal-stores/react-adapter';

const count$ = makeStore(0);

function Counter() {
return (

{(count) =>

{count}

}

);
}
```

### WithReadonlyStores

Similar to `useReadonlyStores`, it takes a collection of `ReadonlyStore`/`Store` and a render prop as its children.

Example using an object:

```tsx
import {makeStore} from 'universal-stores';
import {WithReadonlyStores} from '@universal-stores/react-adapter';

const firstNumber$ = makeStore(4);
const secondNumber$ = makeStore(2);

function Sum() {
return (

{({first, second}) =>

{first + second}

}

);
}
```

Example using an array:

```tsx
import {makeStore} from 'universal-stores';
import {WithReadonlyStores} from '@universal-stores/react-adapter';

const firstNumber$ = makeStore(4);
const secondNumber$ = makeStore(2);

function Sum() {
return (

{([firstNumber, secondNumber]) =>

{firstNumber + secondNumber}

}

);
}
```