@uniono/react

0.1.2 • Public • Published

@uniono/react

The library is designed to work with @uniono/state in React.

useUnion

Import

import useUnion from '@uniono/react'

Description

Hook useUnion has one required argument (template: Object). Based on this template a union will be created. A similar key (for each key of the template) will be created in the union with value result of function useUnion.atom(env, template[key]).

import useUnion from '@uniono/react'

const template = {
	name: '',
	setName: ({ mutations }, newName) => mutations.name.setValue(newName)
}

// Union
// const union = {}
// union.name = new Store('')
// union.setName = new Transaction(union, ({ mutations }, event) => mutations.name.setValue(event.target.value))

const MyComponent = () => {
	const state = useUnion(template)
	const name = state.name       // Value of store union.name
	const setName = state.setName // Method execute of transaction union.setName

	return <input value={name} onChange={setName} />
}

Examples

const template = {
	description: useUnion.mutate(({ union, diMap }) => 
		`Union keys count: ${Object.keys(union)}. Global keys: ${Array.from(diMap.keys()).length}`
	),
	getMe: useUnion.asIs(api.users.getMe),
	menu: useUnion.from({
		open: false,
		toggle: ({ value, mutations }) => mutations.open.toggle()
	}),
	store: '',                 // or useUnion.store('')
	undefinedStore: undefined, // or useUnion.store(),
	arrayStore: [],            // or useUnion.arrayStore([ ]),
	mapStore: new Map(),       // or useUnion.mapStore(new Map()),
	numberStore: 42,           // or useUnion.numberStore(42),
	booleanStore: true,        // or useUnion.booleanStore(true),
	objectStore: {},           // or useUnion.objectStore(42),
	nullStore: null,           // or useUnion.objectStore(null),
	mart: useUnion.mart(       // create mart 
		(value) => value * 2,
		({ numberStore }) => numberStore
	),
	transaction: ({ mutations }, value) => // create transaction
		mutations.numberStore.setValue(value),
	anotherTransaction: useUnion.transaction(
		({ mutations }, value) => mutations.setValue(value),
		({ numberStore }) => numberStore
	),
	// Dependency Injection
	user: useUnion.global('user', useUnion.from({ 
		userName: '',
		setUserName: ({ mutations }, value) => mutations.userName.setValue(value)
	})),
	injection: useUnion.inject('user')
}

Template, which is used to create the next union

const union = {}
union.description = 'Union keys count: 0. Global keys: 0'
union.getMe = api.users.getMe
union.menu = {}
union.menu.open = new BooleanStore(false)
union.menu.toggle = new Transaction(union.menu, ({ mutations }) => mutations.open.toggle())
union.store = new Store('')
union.undefinedStore = new Store()
union.arrayStore = new ArrayStore([])
union.mapStore = new MapStore(new Map())
union.numberStore = new NumberStore(42)
union.booleanStore = new BooleanStore(true)
union.objectStore = new ObjectStore({})
union.nullStore = new ObjectStore(null)
union.mart = new Mart(union.numberStore, (value) => value * 2)
union.transaction = new Transaction(union, ({ mutations }, value) => mutations.numberStore.setValue(value))
union.anotherTransaction = new Transaction(union.numberStore, ({ mutations }, value) => mutations.setValue(value))
union.user = {
	userName: new Store(''),
	setUserName: new Transaction(union.user, ({ mutations }, value) => mutations.userName.setValue(value))
}
union.injection = union.user

Dependency Injection

Dependency Injection based on React Context. The application must be wrapped in DIProvider.

import { DIProvider } from '@uniono/react'
import React from 'react';
import ReactDOM from 'react-dom';

import App from './app';

ReactDOM.render(
	<React.StrictMode>
		<DIProvider>
			<App />
		</DIProvider>
	</React.StrictMode>,
	document.getElementById('root')
);

useUnion.global

Allows to set new value in DI

Argument Type Default Description
id any Injection id
atomTemplate any Injection atom template
{
	user: useUnion.global('user', useUnion.from({ 
		userName: '',
		setUserName: ({ mutations }, value) => mutations.userName.setValue(value)
	})),
	api: useUnion.global('api', useUnion.asIs(api))
}

useUnion.inject

Allow to inject atom from DI

Argument Type Default Description
id any Injection id
map function (x) => x Map injection
{
	usersApi: useUnion.inject('api', ({ users }) => users)
}

Template mutations

useUnion.mutate

useUnion.mutate designed to create an atom based on union & dependency injection state. Function fn will be called at the time of union creation with one argument { union, diMap }, where union is actual union, and diMap is Map (key -> diValue)

Argument Type Default Description
fn function Atom factory
{
	description: useUnion.mutate(({ union, diMap }) => myTemplateAtom)
}

useUnion.asIs

Allows to set value to union without any mutations

Argument Type Default Description
atom any Template atom
{
	getMe: useUnion.asIs(api.users.getMe)
}

useUnion.from

Creates new union from template

Argument Type Default Description
template object or function Union template
{
	menu: useUnion.from({
		open: false,
		toggle: ({ value, mutations }) => mutations.open.toggle()
	})
}

State fabrics

useUnion.store

Creates new Store in union

Argument Type Default Description
value any Store value
{
  str: useUnion.store(''),
  num: useUnion.store(42),
}

useUnion.mart

Creates new Mart in union

Argument Type Default Description
martFn function Function to calculate mart value
unionMap function (x) => x Function to map mart union (With this argument you can control when to recalculate mart)
{
	tab: 'all',
	tasks: [],
	visibleTasks: useUnion.mart(
		({ tab, tasks }) => tasks
			.map((task, index) => ({ ...task, index }))
			.filter((task) => {
				switch (tab) {
					case 'all':
						return true

					case 'active':
						return task.done === false

					case 'completed':
						return task.done === true
					
					default:
						throw new Error(`Unsupported tab ${JSON.stringify(tab)}`)
				}
		}),
		({ tab, tasks }) => ({ tab, tasks })
	)
}

useUnion.transaction

Creates new Transaction in union

Argument Type Default Description
fn function Transaction function
unionMap function (x) => x Function to map transaction union
{
	input: '',
	tasks: [],
	addTask: useUnion.transaction(
		({ value, mutations }) => {
			const { input } = value()
			const title = input.trim()
			if (title.length === 0) {
				return
			}
	
			mutations.input.setValue('')
			mutations.tasks.unshift({ done: false, title })
		}
	)
}

useUnion.arrayStore

Creates new ArrayStore in union

Argument Type Default Description
value Array [] Store value
{
	items: useUnion.arrayStore([ 2, 4, 8, 16 ]) 
	// or items: [ 2, 4, 8, 16 ]
}

useUnion.mapStore

Creates new MapStore in union

Argument Type Default Description
value Map new Map() Store value
{
	map: useUnion.mapStore(new Map())
	// or map: new Map()
}

useUnion.booleanStore

Creates new BooleanStore in union

Argument Type Default Description
atom Boolean false Store value
{
	visible: useUnion.booleamStore(true)
	// or visible: true
}

useUnion.numberStore

Creates new NumberStore in union

Argument Type Default Description
atom Number 0 Store value
{
	answer: useUnion.numberStore(42)
	// or answer: 42
}

useUnion.objectStore

Creates new ObjectStore in union

Argument Type Default Description
atom Object or null Store value
{
	user: useUnion.objectStore({ id: 42, login: 'vpupkin' })
	// or user: { id: 42, login: 'vpupkin' }
}

Readme

Keywords

none

Package Sidebar

Install

npm i @uniono/react

Weekly Downloads

0

Version

0.1.2

License

ISC

Unpacked Size

18.2 kB

Total Files

5

Last publish

Collaborators

  • db-public