@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' }
    }

    Keywords

    none

    Install

    npm i @uniono/react

    DownloadsWeekly Downloads

    4

    Version

    0.1.2

    License

    ISC

    Unpacked Size

    18.2 kB

    Total Files

    5

    Last publish

    Collaborators

    • db-public